android - OnApplyWindowInsetsListener 给出始终为 0 的 systemWindowInsetBottom

标签 android windowinsets

systemWindowInsetBottom 和 stableInsetBottom 都总是 0

我有一个 Activity,它有一个背景纹理,我正在使用 FLAG_LAYOUT_NO_LIMITS 让该背景位于状态和导航栏后面。但我不希望 View 的其他内容位于那些系统 UI 组件的后面。

一开始我想到用resources.getIdentifier("navigation_bar_height", "dimen", "android")来获取导航栏的高度,但是那只是导航的默认高度bar,所以它不会在用户隐藏导航栏的设备上工作。 (三星设备)

然后我发现了 WindowInsets 和 android:fitsSystemWindows="true"

它适用于状态栏,但不适用于导航栏。

在我的 Activity 中

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //These 2 flags don't seem to change anything
    window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN)
    window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR)
    //This flag is required so the background can go behind the navbar
    window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)

    rootView.setOnApplyWindowInsetsListener { _, insets ->
        val topTextViewParams = rootView.tvTop.layoutParams as ViewGroup.MarginLayoutParams
        topTextViewParams.topMargin = insets.systemWindowInsetTop

        val bottomTextViewParams = rootView.tvBottom.layoutParams as ViewGroup.MarginLayoutParams
        bottomTextViewParams.bottomMargin = insets.systemWindowInsetBottom //Inset is always 0

        insets.consumeSystemWindowInsets()
    }
}

还有我的布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:id="@+id/rootView"
        android:background="@color/colorPrimary"
        tools:context=".MainActivity">

    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <TextView
                android:id="@+id/tvBottom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                android:text="Text aligned to bottom of layout with no margin"/>
        <TextView
                android:id="@+id/tvTop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginEnd="8dp"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                android:text="Text aligned to top of layout with no margin"/>
    </android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>

来自运行 API 28 的 Nexus 5x 模拟器的示例屏幕截图。在我运行 API 26 的实际设备上获得相同的结果。

Example Images

如果存在导航栏,我需要做什么才能获得导航栏的实际大小?

最佳答案

我在发帖前花了大约 3 个小时研究这个,发帖后又花了 5 分钟。

那5分钟非常有收获,因为我找到了this post ,这让我尝试添加:

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

到我的 AppTheme,它起作用了。

因此,如果您尝试这样做,请确保您:

override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
    val childCount = childCount
    for (index in 0 until childCount)
        getChildAt(index).dispatchApplyWindowInsets(insets)
    // let children know about WindowInsets

    return insets
}

或者
像我在帖子中所做的那样,使用“物质布局,例如 DrawerLayout 或 CoordinatorLayout”。

确保使用 android:fitsSystemWindows="true"

确保将这些属性添加到您的主题中。

最后 make 在你的 setOnApplyWindowInsetsListener 中做一些事情

关于android - OnApplyWindowInsetsListener 给出始终为 0 的 systemWindowInsetBottom,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53469643/

相关文章:

android - WindowInsetsControllerCompat.OnControllableInsetsChangedListener 不会在插图显示操作上触发

android - 如何在 ViewPager 的 fragment 页面上应用 fitSystemWindows?

c# - 如何在 android/iOS 移动测试中截取屏幕截图 - C#?

Android API 级别 30 setSystemBarsAppearance 不会覆盖主题数据

android - setOnApplyWindowInsetsListener 从未调用过

android - 在Android Studio中更改包名称,包括点数

android - java.lang.UnsatisfiedLinkError : No implementation found for Boolean 错误

Android:如何将密码/安全添加到手机的时间/日期设置以防止用户更改它

android - 如何在不进入设置的情况下更改我的 Android 应用程序中的本地化?