Image for post
Image for post

WindowInsets — Listeners to layouts

Moving where we handle insets to where our views live, layout files

Chris Banes
Apr 12, 2019 · 6 min read

Drawing behind the navigation bar

<BottomNavigationView
android:layout_height="wrap_content"
android:layout_width="match_parent" />
Image for post
Image for post
rootView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<!-- Set the navigation bar to 50% translucent white -->
<item name="android:navigationBarColor">#80FFFFFF</item>
<!-- Since the nav bar is white, we will use dark icons -->
<item name="android:windowLightNavigationBar">true</item>
</style>
Image for post
Image for post
The view is being displayed behind the navigation bar

Handling insets through padding

bottomNav.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(bottom = insets.systemWindowInsetBottom)
insets
}
Image for post
Image for post
The view now has bottom padding which matches the navigation bar size
<BottomNavigationView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingVertical="24dp" />
Image for post
Image for post
The view has the correct top padding, but the intended bottom padding isn’t there
bottomNav.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(
bottom = view.paddingBottom + insets.systemWindowInsetsBottom
)
insets
}
Image for post
Image for post
The accumulated padding after 3 WindowInset dispatches
// Keep a record of the intended bottom padding of the view
val bottomNavBottomPadding = bottomNav.paddingBottom

bottomNav.setOnApplyWindowInsetsListener { view, insets ->
// We've got some insets, set the bottom padding to be the
// original value + the inset value
view.updatePadding(
bottom = bottomNavBottomPadding + insets.systemWindowInsetBottom
)
insets
}
Image for post
Image for post
Finally, what we intended

doOnApplyWindowInsets

bottomNav.doOnApplyWindowInsets { view, insets, padding ->
// padding contains the original padding values after inflation
view.updatePadding(
bottom = padding.bottom + insets.systemWindowInsetBottom
)
}

requestApplyInsetsWhenAttached()

Wrapping it up in a bind

<BottomNavigationView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingVertical="24dp"
app:paddingBottomSystemWindowInsets="@{ true }" />
<BottomNavigationView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingVertical="24dp"
app:paddingBottomSystemWindowInsets="@{ true }"
app:paddingLeftSystemWindowInsets="@{ true }"
/>

android:fitSystemWindows

Ergonomics FTW

Android Developers

The official Android Developers publication on Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade