0

This is a very simple layout with BottomNavigationView

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#EEEEEE">
    <!--
    OUTLINE
    <CoordinatorLayout>
        <AppbarLayout>
             <Toolbar/>
             <TabLayout/>
        <AppbarLayout >
        <ViewPager2/>
        <BottomNavigationView/>
    </CoordinatorLayout>
    -->

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f00"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:background="#ff0"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="@android:color/transparent">

            <ImageView
                android:id="@+id/ivHeader"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/header"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                android:background="#55ff0000"
                android:layout_gravity="top"
                android:layout_marginBottom="?attr/actionBarSize" />

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:background="@android:color/transparent"
                app:tabIconTint="#F57C00"
                app:tabIndicatorColor="#F57C00"
                app:tabIndicatorHeight="4dp"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="#F5F5F5"
                app:tabTextColor="#FFE0B2" />

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

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

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#fff"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:menu="@menu/main" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

I have watched this video from Chris Banes, read this thread, and few others including this one which has top voted answer that says do not use android:fitsSystemWindows which i don't, and have really no idea how exactly insets and setOnApplyListener works and consumes insets.

First of all i set fullscreen with

    private fun hideSystemUI(view: View = window.decorView, isFullScreen: Boolean) {

        var uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE

        if (isFullScreen) {
            // hide status bar
            uiOptions = (
                    uiOptions
//                            or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                            // Views can use nav bar space if set
                            or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
//                            // Removes Status bar
//                            or View.SYSTEM_UI_FLAG_FULLSCREEN
//                            // hide nav bar
//                            or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    )
        }

        view.systemUiVisibility = uiOptions
    }

by passing root CoordinatorLayout as parameter to this function. Set theme as

@color/status_bar_color true @color/nav_bar_color

And initial image without setting any insets

enter image description here

As can be seen in the Toolbar is below statusBar while BottomNavigationView is below NavBar.

So i set setOnApplyWindowInsetsListener

    bottomNav.setOnApplyWindowInsetsListener { view, insets ->
        view.updatePadding(bottom = insets.systemWindowInsetBottom)
        insets
    }

but it does not get called. So i set insets on AppbarLayout, CollapsingLayout, and ImageView like i would do with android:fitsSystemWindows

appbar.setOnApplyWindowInsetsListener { view, insets ->
    view.updatePadding(top = insets.systemWindowInsetTop)
    insets
}

collapsingToolbar.setOnApplyWindowInsetsListener { view, insets ->
    view.updatePadding(top =  insets.systemWindowInsetTop)
    insets
}

ivHeader.setOnApplyWindowInsetsListener { view, insets ->
    view.updatePadding(top = insets.systemWindowInsetTop)
    insets
}

And i get this

enter image description here

Red background belongs to AppbarLayout, yellow background belongs CollapsingToolbarLayout.

Now, BottomNavigationView's setOnApplyWindowInsetsListener gets called and it's inset get fixed i guess.

My question is why doesn't it get called without calling insets for CollapsingToolbarLayout, and why there is a gap for CollapsingToolbarLayout and AppbarLayout?

Thracian
  • 43,021
  • 16
  • 133
  • 222

1 Answers1

1

I found out that CollapsingToolbarLayout has a bug that prevents receiving insets which is mentioned in issues on github. Setting layouts above AppBarLayout makes sure that other views receive insets.

But i still not be able to find how to apply insets/padding correctly for the layout in the question.

Thracian
  • 43,021
  • 16
  • 133
  • 222