Android - fitsSystemWindows 问题 属性
Android - Problem with fitsSystemWindows property
我需要你的帮助来理解一个奇怪的行为。当我将 fitsSystemWindows 属性 设置为 'true' 时,导航栏隐藏了我布局的某些部分,请参见下图:
当我设置为 false 时,我有这种行为(没关系):
当我阅读 Android 文档和 Whosebug 上的许多帖子时,我理解它应该与此行为完全相反:https://developer.android.com/reference/android/view/View#attr_android:fitsSystemWindows。
第一种情况 fitsSystemWindows='true' 应该没问题,第二种情况应该被导航栏隐藏,我错了吗?
有人可以向我解释发生了什么事吗?我的 targetVersionSdk 是 29,我在许多版本(Android 6,7 10 和 11)上测试过它。也许它特定于 CoordinatorLayout ?感谢您的解释:)
这是我的 xml 布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="[true or false]">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.AppBarLayout>
[...]
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginEnd="@dimen/activity_vertical_margin"
android:src="@drawable/ic_arrow_forward_white_24dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
我认为该视图按预期工作。首先,您需要了解插图及其传递方式。 fitsSystemWindow
的默认行为是消耗所有插图并将它们应用为填充。但是 CoordinatorLayout、DrawerLayout 等 ViewGroup 会覆盖此行为。
这是 CoordinatorLayout 中覆盖该行为的代码片段。
private void setupForInsets() {
if (Build.VERSION.SDK_INT < 21) {
return;
}
if (ViewCompat.getFitsSystemWindows(this)) {
if (mApplyWindowInsetsListener == null) {
mApplyWindowInsetsListener =
new androidx.core.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v,
WindowInsetsCompat insets) {
return setWindowInsets(insets);
}
};
}
ViewCompat.setOnApplyWindowInsetsListener(this, mApplyWindowInsetsListener);
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else {
ViewCompat.setOnApplyWindowInsetsListener(this, null);
}
}
如您所见,在 CoordinatorLayout 中应用 fitsSystemWindow
会导致其呈现系统 UI 下的内容。您需要做的是添加系统提供的 insets 并将其作为 margin 或 padding 应用到顶部和底部视图。
您可以使用 setOnApplyWindowInsetsListener()
来侦听插入并应用它。假设您有 bottomNav
作为底部视图,那么您可以执行类似的操作来说明底部插图。
ViewCompat.setOnApplyWindowInsetsListener(bottomNav) { view, insets ->
bottomNav.updatePadding(bottom = insets.systemWindowInsetBottom)
insets
}
您可以在 this 博客 post 中了解有关插图的更多信息。
我需要你的帮助来理解一个奇怪的行为。当我将 fitsSystemWindows 属性 设置为 'true' 时,导航栏隐藏了我布局的某些部分,请参见下图:
当我设置为 false 时,我有这种行为(没关系):
当我阅读 Android 文档和 Whosebug 上的许多帖子时,我理解它应该与此行为完全相反:https://developer.android.com/reference/android/view/View#attr_android:fitsSystemWindows。 第一种情况 fitsSystemWindows='true' 应该没问题,第二种情况应该被导航栏隐藏,我错了吗?
有人可以向我解释发生了什么事吗?我的 targetVersionSdk 是 29,我在许多版本(Android 6,7 10 和 11)上测试过它。也许它特定于 CoordinatorLayout ?感谢您的解释:)
这是我的 xml 布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="[true or false]">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.AppBarLayout>
[...]
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginEnd="@dimen/activity_vertical_margin"
android:src="@drawable/ic_arrow_forward_white_24dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
我认为该视图按预期工作。首先,您需要了解插图及其传递方式。 fitsSystemWindow
的默认行为是消耗所有插图并将它们应用为填充。但是 CoordinatorLayout、DrawerLayout 等 ViewGroup 会覆盖此行为。
这是 CoordinatorLayout 中覆盖该行为的代码片段。
private void setupForInsets() {
if (Build.VERSION.SDK_INT < 21) {
return;
}
if (ViewCompat.getFitsSystemWindows(this)) {
if (mApplyWindowInsetsListener == null) {
mApplyWindowInsetsListener =
new androidx.core.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v,
WindowInsetsCompat insets) {
return setWindowInsets(insets);
}
};
}
ViewCompat.setOnApplyWindowInsetsListener(this, mApplyWindowInsetsListener);
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else {
ViewCompat.setOnApplyWindowInsetsListener(this, null);
}
}
如您所见,在 CoordinatorLayout 中应用 fitsSystemWindow
会导致其呈现系统 UI 下的内容。您需要做的是添加系统提供的 insets 并将其作为 margin 或 padding 应用到顶部和底部视图。
您可以使用 setOnApplyWindowInsetsListener()
来侦听插入并应用它。假设您有 bottomNav
作为底部视图,那么您可以执行类似的操作来说明底部插图。
ViewCompat.setOnApplyWindowInsetsListener(bottomNav) { view, insets ->
bottomNav.updatePadding(bottom = insets.systemWindowInsetBottom)
insets
}
您可以在 this 博客 post 中了解有关插图的更多信息。