如何固定 Snackbar 的高度和位置?
How to fix the Snackbar height and position?
在 Android 支持库 24.1.1 上,Snackbar 工作正常:
然后从 Android 支持库 24.2.0 开始,Snackbar 开始表现如下:
在库revision history上,有如下语句:
Behavior changes: Snackbar now draws behind the navigation bar if the status bar is translucent.
但问题是我的应用程序是全屏的,没有导航栏或状态栏。我该如何解决?
在你的小吃店里使用这个,
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.BOTTOM;
查看此答案 并替换
params.setMargins(params.leftMargin,
params.topMargin,
params.rightMargin,
params.bottomMargin + ScreenUtils.getNavigationBarHeight(activity));
至
params.setMargins(params.leftMargin,
params.topMargin,
params.rightMargin,
params.bottomMargin - ScreenUtils.getNavigationBarHeight(activity));
我最近通过从 Snackbar 视图的底部边缘减去导航栏高度解决了这个问题。
首先我们需要导航栏的高度。我在此处标记为正确的答案中找到了代码:
接下来,使用以下代码调整 Snackbar 底部边距:
final Snackbar snackbar = Snackbar.make(findViewById(R.id.fullscreen_content),
message, Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
// Adjust Snackbar height for fullscreen immersive mode
int navbarHeight = getNavigationBarSize(this).y;
CoordinatorLayout.LayoutParams parentParams = (CoordinatorLayout.LayoutParams) snackbarView.getLayoutParams();
parentParams.setMargins(0, 0, 0, 0 - navbarHeight);
snackbarView.setLayoutParams(parentParams);
snackbar.show();
请注意,我使用了 CoordinatorLayout 的 LayoutParams。您应该将 CoordinatorLayout 替换为您传递给 Snackbar.make()
函数的任何父布局类型(在我的例子中,R.id.fullscreen_content
是一个 CoordinatorLayout)。使用 CoordinatorLayout 的好处是它允许通过滑动作为标准行为来关闭 Snackbars。
接受的答案适用于旧版本的支持库,其中 Snackbar
只是一个矩形视图。通过将边距更改为负值实际发生的只是切断 SnackbarLayout
的底部(Snackbar
的容器布局),因此 Snackbar
具有圆角的较新版本这个解决方案看起来很糟糕。
实际发生的是填充被添加到容器中,因此正确固定高度的方法是将填充重置为正确的数量。您可以通过添加额外的 OnApplyWindowInsetsListener
来做到这一点,如下所示(将底部填充设置为与顶部相同使 Snackbar
看起来正常):
ViewCompat.setOnApplyWindowInsetsListener(snackbar.view) { v, insets ->
v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, v.paddingTop)
insets
}
然后,由于 Snackbar
现在是正确的高度但出现在半透明导航栏后面,您可以通过底部插图的值增加底部边距:
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, v.paddingTop)
val params = v.layoutParams as ViewGroup.MarginLayoutParams
params.updateMargins(
params.leftMargin,
params.topMargin,
params.rightMargin,
params.bottomMargin + insets.systemWindowInsetBottom
)
v.layoutParams = params
insets
}
这实际上已在 Material 1.1.0 alpha 库中修复(该库现在更改边距而不是填充),但它们可能尚未准备好用于生产。
如果您只关心身高而不是位置,那么请准备好让您大吃一惊! :D
将您的小吃栏内容设置为:
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Your SnackBar message',
),
SizedBox(
height: 70, // Your desired height
)
],
))
另一种方式是
Snackbar snackbar = Snackbar.make(view, ...);
View snackBarView = snackbar.getView();
ViewCompat.setFitsSystemWindows(snackBarView, false);
ViewCompat.setOnApplyWindowInsetsListener(snackBarView, null);
这将在沉浸式模式下禁用额外的底部填充。
现在是 2020 年,我也不知道这是否相关,但是当我使用 android 10 手势导航时,我的小吃店底部有一些填充物。 None 以上适用于我的情况。我终于用一条超级简单的线修复了它:
val snackbar = Snackbar.make(view, message, duration)
snackbar.isGestureInsetBottomIgnored = true // here
snackbar.show()
希望对您有所帮助。
在 Android 支持库 24.1.1 上,Snackbar 工作正常:
然后从 Android 支持库 24.2.0 开始,Snackbar 开始表现如下:
在库revision history上,有如下语句:
Behavior changes: Snackbar now draws behind the navigation bar if the status bar is translucent.
但问题是我的应用程序是全屏的,没有导航栏或状态栏。我该如何解决?
在你的小吃店里使用这个,
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.BOTTOM;
查看此答案
params.setMargins(params.leftMargin,
params.topMargin,
params.rightMargin,
params.bottomMargin + ScreenUtils.getNavigationBarHeight(activity));
至
params.setMargins(params.leftMargin,
params.topMargin,
params.rightMargin,
params.bottomMargin - ScreenUtils.getNavigationBarHeight(activity));
我最近通过从 Snackbar 视图的底部边缘减去导航栏高度解决了这个问题。
首先我们需要导航栏的高度。我在此处标记为正确的答案中找到了代码:
接下来,使用以下代码调整 Snackbar 底部边距:
final Snackbar snackbar = Snackbar.make(findViewById(R.id.fullscreen_content),
message, Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
// Adjust Snackbar height for fullscreen immersive mode
int navbarHeight = getNavigationBarSize(this).y;
CoordinatorLayout.LayoutParams parentParams = (CoordinatorLayout.LayoutParams) snackbarView.getLayoutParams();
parentParams.setMargins(0, 0, 0, 0 - navbarHeight);
snackbarView.setLayoutParams(parentParams);
snackbar.show();
请注意,我使用了 CoordinatorLayout 的 LayoutParams。您应该将 CoordinatorLayout 替换为您传递给 Snackbar.make()
函数的任何父布局类型(在我的例子中,R.id.fullscreen_content
是一个 CoordinatorLayout)。使用 CoordinatorLayout 的好处是它允许通过滑动作为标准行为来关闭 Snackbars。
接受的答案适用于旧版本的支持库,其中 Snackbar
只是一个矩形视图。通过将边距更改为负值实际发生的只是切断 SnackbarLayout
的底部(Snackbar
的容器布局),因此 Snackbar
具有圆角的较新版本这个解决方案看起来很糟糕。
实际发生的是填充被添加到容器中,因此正确固定高度的方法是将填充重置为正确的数量。您可以通过添加额外的 OnApplyWindowInsetsListener
来做到这一点,如下所示(将底部填充设置为与顶部相同使 Snackbar
看起来正常):
ViewCompat.setOnApplyWindowInsetsListener(snackbar.view) { v, insets ->
v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, v.paddingTop)
insets
}
然后,由于 Snackbar
现在是正确的高度但出现在半透明导航栏后面,您可以通过底部插图的值增加底部边距:
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, v.paddingTop)
val params = v.layoutParams as ViewGroup.MarginLayoutParams
params.updateMargins(
params.leftMargin,
params.topMargin,
params.rightMargin,
params.bottomMargin + insets.systemWindowInsetBottom
)
v.layoutParams = params
insets
}
这实际上已在 Material 1.1.0 alpha 库中修复(该库现在更改边距而不是填充),但它们可能尚未准备好用于生产。
如果您只关心身高而不是位置,那么请准备好让您大吃一惊! :D
将您的小吃栏内容设置为:
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Your SnackBar message',
),
SizedBox(
height: 70, // Your desired height
)
],
))
另一种方式是
Snackbar snackbar = Snackbar.make(view, ...);
View snackBarView = snackbar.getView();
ViewCompat.setFitsSystemWindows(snackBarView, false);
ViewCompat.setOnApplyWindowInsetsListener(snackBarView, null);
这将在沉浸式模式下禁用额外的底部填充。
现在是 2020 年,我也不知道这是否相关,但是当我使用 android 10 手势导航时,我的小吃店底部有一些填充物。 None 以上适用于我的情况。我终于用一条超级简单的线修复了它:
val snackbar = Snackbar.make(view, message, duration)
snackbar.isGestureInsetBottomIgnored = true // here
snackbar.show()
希望对您有所帮助。