I'm trying to setup fullscreen activity for Android 10 using insets. I wanted to have an image in toolbar drawn behind status bar. I've tried to use android:fitsSystemWindows
flag in different combinations, but it doesn't work, AppBarLayout
doesn't have correct padding and status bar slightly overlaps toolbar menu controls. So I've used convenient WindowInsetsCompat
wrapper, Insetter library by Chris Banes, to set paddings according to system window insets.
Here is my layout:
<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:id="@+id/book_activity_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
tools:context="com.bookcrossing.mobile.ui.bookpreview.BookActivity"
>
<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
...
</androidx.core.widget.NestedScrollView>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbarContainer"
android:layout_width="match_parent"
android:layout_height="220dp"
>
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="bottom"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:titleEnabled="true"
app:toolbarId="@id/toolbar"
>
<ImageView
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/cover_description"
android:scaleType="centerCrop"
android:cropToPadding="true"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.5"
/>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
tools:title="War and Peace"
/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_padding"
android:clickable="true"
android:focusable="true"
android:src="@drawable/ic_turned_in_not_white_24dp"
app:layout_anchor="@id/toolbar_container"
app:layout_anchorGravity="bottom|right|end"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here is how I set the paddings in code:
Insetter.setOnApplyInsetsListener(toolbarContainer, (view, windowInsets, initial) -> {
view.setPadding(initial.getPaddings().getLeft(),
windowInsets.getSystemWindowInsetTop() + initial.getPaddings().getTop(),
initial.getPaddings().getRight(), initial.getPaddings().getBottom());
});
Insetter.setOnApplyInsetsListener(cover, (view, windowInsets, initial) -> {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
params.topMargin = windowInsets.getSystemWindowInsetTop() + initial.getMargins().getTop();
view.setLayoutParams(params);
});
Insetter.setOnApplyInsetsListener(nestedScrollView, (view, windowInsets, initial) -> {
view.setPadding(initial.getPaddings().getLeft(), initial.getPaddings().getTop(),
initial.getPaddings().getRight(),
windowInsets.getSystemWindowInsetBottom() + initial.getPaddings().getBottom());
});
Insetter.setOnApplyInsetsListener(favorite, (view, windowInsets, initialPadding) -> {
view.setPadding(initialPadding.getPaddings().getLeft(), initialPadding.getPaddings().getTop(),
windowInsets.getSystemWindowInsetRight() + initialPadding.getPaddings().getRight(),
initialPadding.getPaddings().getBottom());
});
I set window flags for the fullscreen mode:
root.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
And this is the result pictured:
Status bar is set to be transparent, blue color is from the toolbar that has top padding.
As a final result, I would like image to be drawn behind the status bar, is it possible at all?
I'm testing on the Android 10 emulator.
As I remember you don't need to support paddings in CoordinatorLayout manually, please see
setupForInsets
function inCoordinatorLayout
class. To support drawing behind status bar you should setandroid:fitsSystemWindows="true"
forCoordinatorLayout
:And as I understand you do not need
animateLayoutChanges
here. It's responsible for animations in layout changes such as removing/adding and showing/hiding views.