material-components / material-components/material-components-android

CollapsingToolbar and MaterialToolbar bug in height when adapting edge-to-edge enforcement

Open
#4,482 6 comments 3 reactions 1 assignee View on GitHub

@pekingme is already working on this.

Since Dec 20, 2024.

bug Widget: TopAppBar
Dominant language
Java
Stars
17.4k
Forks
3.2k
PR merge metrics
No merged PRs in 30d

Description

Description:
Handling window insets to adapt edge-to-edge enforcement of Android 15 requires the Toolbar height to be set as wrap_content since we usually add padding top on it via ViewCompat.setOnApplyWindowInsetsListener. This however is not possible when a Toolbar is inside CollapsingToolbar since setting the Toolbar's height to wrap_content will make its height matching the CollapsingToolbar height based on this previous issue.

Expected behavior: Enable edge-to-edge enforcement when a Toolbar collapsed using CollapsingToolbar.

This is edge-to-edge, it draws the whole content behind system bars despite Toolbar's height here is incorrect and need fixing due to this bug. The below image is for reference and is not using CollapsingToolbar.
image
image

Source code:
This code allows the drawing of ImageView behind status bar but when we collapse the Toolbar, it is not edge-to-edge.

<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"
    tools:context=".presentation.NewsDetailActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/collapsingToolbarLayoutLargeSize"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|snap|enterAlways|enterAlwaysCollapsed"
            app:maxLines="3">

            <androidx.appcompat.widget.AppCompatImageView
                android:id="@+id/featuredImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:adjustViewBounds="true"
                android:fitsSystemWindows="true"
                android:src="@drawable/logo_dynamic_placeholder"
                android:background="@color/mdc_colorWhiteDark_Primary"
                app:layout_collapseMode="parallax" />

            <com.google.android.material.appbar.MaterialToolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/transparent"
                app:navigationIcon="?attr/homeAsUpIndicator"
                app:navigationContentDescription="@string/abc_action_bar_up_description"
                app:layout_collapseMode="pin"
                app:layout_scrollFlags="scroll|snap|enterAlways|enterAlwaysCollapsed"
                app:title="@tools:sample/cities" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.appcompat.widget.LinearLayoutCompat
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <org.sufficientlysecure.htmltextview.HtmlTextView
                android:id="@+id/description_html_txt_v"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingHorizontal="@dimen/space_12"
                android:paddingTop="@dimen/space_48"
                android:paddingBottom="@dimen/space_12"
                android:text="@tools:sample/lorem/random"
                android:textSize="@dimen/textSize14" />

            <androidx.appcompat.widget.LinearLayoutCompat
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingVertical="@dimen/space_16"
                android:visibility="visible">

                <com.google.android.material.textview.MaterialTextView
                    android:id="@+id/labelTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingHorizontal="@dimen/space_12"
                    android:paddingBottom="@dimen/space_8"
                    android:text="@string/related_content"
                    android:textAllCaps="true"
                    android:textColor="@color/mdc_colorPrimaryDark_Accent"
                    android:textSize="@dimen/textSize24" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/feedRecycler"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:clipToPadding="false"
                    android:nestedScrollingEnabled="false"
                    android:paddingHorizontal="@dimen/space_12" />

            </androidx.appcompat.widget.LinearLayoutCompat>

        </androidx.appcompat.widget.LinearLayoutCompat>

    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/visitWeb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:useCompatPadding="true"
        android:contentDescription="@string/news"
        android:src="@drawable/ic_open_tab"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="bottom|end" />

    <FrameLayout
        android:id="@+id/ad_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center|bottom" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

This is not edge-to-edge, the content is being cut and not drawn behind system bars.
image
image
image

Attempt 1

What I did so far is to remove fitsSystemWindows=true in AppBarLayout, which resulted to this.
image
image

Adding the runtime padding adjustment.

ViewCompat.setOnApplyWindowInsetsListener(root) { _: View, insets: WindowInsetsCompat ->
    val barInset = insets.getInsets(WindowInsetsCompat.Type.systemBars())
    // Add padding to this view based on status bar inset
    toolbar.updatePadding(top = barInset.top)
    // Return WindowInsetsCompat.CONSUMED if you don't want the window insets to keep passing down
    // to descendant views including all views of Fragment(s) under this Fragment
    WindowInsetsCompat.CONSUMED
}
Conclusion 1

Almost but the collapsed Toolbar height is in mess.
image
image
image

Minimal sample app repro: N/A

Android API version: Android 15

Material Library version: 1.12.0

Device: AVD/Emulator

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.