Reputation: 430
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.
Upvotes: 4
Views: 1499
Reputation: 625
Your flags seem to be wrong. You set the flag for the navigation bar while you should be setting the one for the status bar.
Here is the code I use (Kotlin):
requireActivity().window?.decorView?.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
to make the UI draw behind status bar without the status bar getting hidden. Then I use this extension function I use on views that should not overlap with the status bar like buttons and other controls:
fun View.alignBelowStatusBar() {
this.setOnApplyWindowInsetsListener { view, insets ->
val params = view.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = insets.systemWindowInsetTop
view.layoutParams = params
insets
}
}
So the first flags would ensure your backgrounds/images go under the status bar. The second one is to make sure that your controls are not overlayed by the status bar.
Upvotes: 1
Reputation: 3659
As I remember you don't need to support paddings in CoordinatorLayout manually, please see setupForInsets
function in CoordinatorLayout
class. To support drawing behind status bar you should set android:fitsSystemWindows="true"
for CoordinatorLayout
:
<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"
>
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.
Upvotes: 0