[CollapsingToolbarLayout] Consuming system window insets blocks sibling views from receiving insets
See original GitHub issueDescription: CollapsingToolbarLayout is listening to window insets and inside the listener calls:
// Consume the insets. This is done so that child views with fitSystemWindows=true do not
// get the default padding functionality from View
return insets.consumeSystemWindowInsets();
While consuming the insets, so its children do not receive them makes sense, due to how insets are dispatched by system, this causes insets to not be dispatched also to its sibling views.
Maybe it could only consume the insets only if android:fitsSystemWindows="true"
?
After quite some trial & error I discovered a workaround: if I set my own insets listener (doing nothing) on the CollapsingToolbarLayout, I can avoid it consuming the insets. But this feels like hacking around it instead of proper solution.
Expected behavior: System window insets are also dispatched to its sibling views.
Source code:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="160dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
ViewCompat.setOnApplyWindowInsetsListener(recyclerView) { _, insets ->
// this will not be called
insets
}
ViewCompat.setOnApplyWindowInsetsListener(appBar) { _, insets ->
// this is called ok
insets
}
}
Android API version: I checked on api 29.
Material Library version: 1.1.0, 1.2.0-alpha06
Issue Analytics
- State:
- Created 3 years ago
- Reactions:11
- Comments:6 (1 by maintainers)
Top GitHub Comments
I also stumbled over this on version 1.2.0-alpha04. A
OnApplyWindowInsetsListener
onBottomNavigationView
would not be called anymore as soon as I navigate to a view containingCollapsingToolbarLayout
, resulting in the BottomNavView being occluded by the system navigation bar.My current workaround is opting out of the consuming behavior by removing the listener on the
CollapsingToolbarLayout
:ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, null)
Would be great if this issue could be resolved.
Very confusing behaviour to encounter. Though the provided workaround does work.
When targeting API 30+ and using the new
WindowsInsetsCompat
andWindowInsetsControllerCompat
API, this behaviour is only seen when the legacy implementation is used (up to API 29) and not on API 30+.This is extra worrying as developers use a single API and expect similar behavior on all devices.
The proposed changed to only do this with
fitsSystemWindows="true"
seems good, as it’s available as opt-in when needed but does cause this unexpected issue by default.