chrisbanes / insetter

Insetter is a library to help apps handle WindowInsets more easily
https://chrisbanes.github.io/insetter
Apache License 2.0
1.13k stars 42 forks source link

Cann't set inset for MaterialToolbar inside CollapsingToolbarLayout #127

Closed maxrave-dev closed 1 day ago

maxrave-dev commented 1 year ago

Inside my XML

<androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rootFull">
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/topAppBarLayout">
            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:layout_width="match_parent"
                android:layout_height="300sp"
                android:id="@+id/topAppBar"
                app:title="HIEUTHUHAI"
                app:expandedTitleTextAppearance="@style/artist_name"
                app:expandedTitleTextColor="@android:color/white"
                app:collapsedTitleTextAppearance="@style/TextAppearance.Material3.TitleMedium"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:contentScrim="?attr/colorSurface">
                <ImageView
                    android:id="@+id/ivArtistImage"
                    android:layout_width="match_parent"
                    android:layout_height="300dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/artist_thumbail"
                    app:layout_collapseMode="parallax"
                    app:layout_collapseParallaxMultiplier="0.7" />
                <com.google.android.material.appbar.MaterialToolbar
                    android:id="@+id/toolBar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:navigationIcon="@drawable/baseline_arrow_back_ios_24"
                    app:layout_collapseMode="pin"
                    app:popupTheme="@style/Widget.Material3.PopupMenu.Overflow">

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

In my fragment onCreateView:

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentArtistBinding.inflate(inflater, container, false)
        binding.toolBar.applyInsetter {
            type(statusBars = true) {
                padding()
            }
        }

        return binding.root
    }

My result: image image

Toolbar still be overlap How to fix it? Thanks for make a best library

mateuszkwiecinski commented 1 year ago

@maxrave-dev I'm fairly sure you're facing this issue: https://github.com/material-components/material-components-android/issues/1310 and the workaround is to clear collapsing toolbar insets via ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, null)

PMARZV commented 1 year ago

@mateuszkwiecinski hi, this fixes the problem but creates another. When setting the listener to null, on api >31 or >32 (i dont fully remember), the scrim color set in Collapsing Toolbar is transparent although i set a different color, programmatically cant change it neither. Api <=30 doesnt seem to face this problem and show scrim color correctly. Any suggestion?? Ive been stuck on this problem for so long and looking on te internet doesnt seem to help☹ EDIT: IF SOMEONE COULD HELP ME I WOULD APPRECIATE IT SO MUCH

c-b-h commented 11 months ago

I managed to solve a similar issue:

https://github.com/chrisbanes/insetter/assets/14194998/cddbd19f-d74c-4e13-8a7e-2a298ac87a59 Notice the toolbar not being correctly inset due to CollapsingToolbarLayout consumption of insets.

Next is after forcefully removing OnApplyWindowInsetsListener from CollapsingToolbarLayout i.e.

ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, null)

https://github.com/chrisbanes/insetter/assets/14194998/4700e1c1-c9fe-4a2f-a046-b2545c3ce5a0 As seen now CollapsingToolbarLayout fails to handle scrim of the Toolbar correctly.

And the workaround for this problem is by updating the CollapsingToolbarLayout's scrimVisibleHeightTrigger by applying a custom OnApplyWindowInsetsListener to the CollapsingToolbarLayout:

class CustomOnApplyWindowInsetsListener(
    private val toolbar: Toolbar
) : OnApplyWindowInsetsListener {
    private var lastInsets: WindowInsetsCompat? = null
    override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
        if (v !is CollapsingToolbarLayout) return insets
        var newInsets: WindowInsetsCompat? = null

        if (ViewCompat.getFitsSystemWindows(v)) {
            // If we're set to fit system windows, keep the insets
            newInsets = insets
        }

        // If our insets have changed, keep them and invalidate the scroll ranges...
        if (lastInsets != newInsets) {
            lastInsets = newInsets
            v.requestLayout()
        }

        toolbar.doOnLayout { toolbar ->
            v.scrimVisibleHeightTrigger =
                insets.getInsets(WindowInsetsCompat.Type.systemBars()).top +
                        toolbar.bottom
        }

        return insets // Unlike the original handling, insets aren't consumed (in order to let Toolbar apply margin based on insets)
    }
}

And the result will look like this:

https://github.com/chrisbanes/insetter/assets/14194998/445c4d65-8dd5-4fe9-8197-4a89a4558105