systemWindowInsetBottom AND stableInsetBottom are both always 0
I have an Activity, that has a background texture, and I am using FLAG_LAYOUT_NO_LIMITS to let that background go behind the status and navigation bar. But I don't want the other contents of the view to go behind those system UI components.
At first I thought of using resources.getIdentifier("navigation_bar_height", "dimen", "android")
to get the height of the navigation bar, but that's just the default height of the navigation bar, so it won't work on devices where the user has hidden the navigation bar. (Samsung devices)
Then I found out about WindowInsets and android:fitsSystemWindows="true"
It works for the status bar, but it does not work for the navigation bar.
In my 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()
}
}
And my layout
<?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>
Example screenshots from Nexus 5x Emulator running API 28. Getting same results on my actual device running API 26.
What do I have to do to get the actual size of the navigation bar, if it is present?
I spend like 3 hours researching this before I posted and then 5 minutes after I posted.
Those 5 minutes were very fruitful, because I found this post, which led me to try adding:
To my AppTheme, which worked.
So, if you're trying to do this, make sure you:
OR
Use a "materialish layout such as DrawerLayout or CoordinatorLayout" like I did in my post.
Make sure to use android:fitsSystemWindows="true"
Make sure to add those properties to your theme.
And finally make to do something in your setOnApplyWindowInsetsListener