Android KitKat:Snackbar 不在屏幕底部
Android KitKat: Snackbar is not in the bottom of the screen
我在我的应用程序中添加了一个 Snackbar。问题是在 API 19 中它不在屏幕底部。
在API21就可以了。这是我的布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data />
<android.support.design.widget.CoordinatorLayout
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/home_search_input_hint"
android:inputType="text"
android:maxLength="30"
android:maxLines="1"/>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>
</layout>
还有我的OnCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_home);
super.onCreate(savedInstanceState);
// binding
binding = DataBindingUtil.setContentView(this, R.layout.activity_home);
// snackbar test
Snackbar snackbar = Snackbar.make(binding.root, "Snackbar", Snackbar.LENGTH_INDEFINITE);
snackbar.show();
}
你有什么解决办法吗?
更新:底部的边距似乎是随机的,我重新运行模拟器看到了这个。
还有这个
可以通过将显示 snackbar 的代码移动到 onGlobalLayout() 来避免这个问题,如下所示。
binding.root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
// snackbar test
Snackbar snackbar = Snackbar.make(binding.root, "Snackbar", Snackbar.LENGTH_INDEFINITE);
snackbar.show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
binding.root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
binding.root.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
如果您使用 26 或 27 支持,可能是这个已知错误:Google Issue Tracker: Snackbar wrong placement on the Android 4x versions
要解决此问题,请在显示 Snackbar 之前使用一个小的时间延迟。如果您想在屏幕显示时立即显示 Snackbar,则需要这样做,onCreateView()
或 onCreate()
。
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// For com.android.support:design:v26 or v27, use a small
// time delay, to prevent bottom gap bug on Android 4.4
if (isAdded()) { snackbar.show(); }
}
}, 500);
因为你有时间延迟,请记住通过检查 isAdded()
或检查 getActivity() != null
.
来防止空 Activity
这是一个bug,还没有修复。
解决方法 - 在棒棒糖之前的设备上出现小延迟。
UI.
上的延迟不明显
将这些方法放入您的基础片段和基础 activity 并随处使用:
protected ViewGroup getRootView() {
return (ViewGroup) getView().getParent();
}
protected void showSnackbar(@StringRes int resId) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
new Handler().postDelayed(() -> Snackbar.make(getRootView(), resId, Snackbar.LENGTH_SHORT).show(), 200);
} else {
Snackbar.make(getRootView(), resId, Snackbar.LENGTH_SHORT).show();
}
}
protected void showSnackbar(String message) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
new Handler().postDelayed(() -> Snackbar.make(getRootView(), message, Snackbar.LENGTH_SHORT).show(), 200);
} else {
Snackbar.make(getRootView(), message, Snackbar.LENGTH_SHORT).show();
}
}
我在我的应用程序中添加了一个 Snackbar。问题是在 API 19 中它不在屏幕底部。
在API21就可以了。这是我的布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data />
<android.support.design.widget.CoordinatorLayout
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/home_search_input_hint"
android:inputType="text"
android:maxLength="30"
android:maxLines="1"/>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>
</layout>
还有我的OnCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_home);
super.onCreate(savedInstanceState);
// binding
binding = DataBindingUtil.setContentView(this, R.layout.activity_home);
// snackbar test
Snackbar snackbar = Snackbar.make(binding.root, "Snackbar", Snackbar.LENGTH_INDEFINITE);
snackbar.show();
}
你有什么解决办法吗?
更新:底部的边距似乎是随机的,我重新运行模拟器看到了这个。
还有这个
可以通过将显示 snackbar 的代码移动到 onGlobalLayout() 来避免这个问题,如下所示。
binding.root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
// snackbar test
Snackbar snackbar = Snackbar.make(binding.root, "Snackbar", Snackbar.LENGTH_INDEFINITE);
snackbar.show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
binding.root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
binding.root.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
如果您使用 26 或 27 支持,可能是这个已知错误:Google Issue Tracker: Snackbar wrong placement on the Android 4x versions
要解决此问题,请在显示 Snackbar 之前使用一个小的时间延迟。如果您想在屏幕显示时立即显示 Snackbar,则需要这样做,onCreateView()
或 onCreate()
。
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// For com.android.support:design:v26 or v27, use a small
// time delay, to prevent bottom gap bug on Android 4.4
if (isAdded()) { snackbar.show(); }
}
}, 500);
因为你有时间延迟,请记住通过检查 isAdded()
或检查 getActivity() != null
.
这是一个bug,还没有修复。
解决方法 - 在棒棒糖之前的设备上出现小延迟。 UI.
上的延迟不明显将这些方法放入您的基础片段和基础 activity 并随处使用:
protected ViewGroup getRootView() {
return (ViewGroup) getView().getParent();
}
protected void showSnackbar(@StringRes int resId) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
new Handler().postDelayed(() -> Snackbar.make(getRootView(), resId, Snackbar.LENGTH_SHORT).show(), 200);
} else {
Snackbar.make(getRootView(), resId, Snackbar.LENGTH_SHORT).show();
}
}
protected void showSnackbar(String message) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
new Handler().postDelayed(() -> Snackbar.make(getRootView(), message, Snackbar.LENGTH_SHORT).show(), 200);
} else {
Snackbar.make(getRootView(), message, Snackbar.LENGTH_SHORT).show();
}
}