TransWikia.com

CollapsingToolbarLayout causes RecyclerView's bottom to be underscreen

Stack Overflow Asked by FindOutIslamNow on December 22, 2021

I have AppBarLayout with fixed height (@dimen/app_bar_height = 200dp), which has CollapsingToolbarLayout in it. When scrolling down, part of recyclerview is hidden under screen bottom.

If I remove scroll flags (ie. disable scrolling collapse) I remove app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" from CollapsingToolbarLayout then it is normally aligning screen bottom.

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:fitsSystemWindows="true"
    tools:ignore="MergeRootFrame">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <!-- Problem HERE in app:layout_scrollFlags -->
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:expandedTitleGravity="bottom"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" 
            app:toolbarId="@+id/toolbar">

            <TextView
                android:text="Hello, Hello, Hello, Hello, Hello, Hello, Hello, Hello, Hello, Hello"
                android:textSize="19sp"
                android:textStyle="bold"
                android:id="@+id/txtDescr"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.5"/>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/detail_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|start"
                android:layout_margin="@dimen/fab_margin"
                app:layout_collapseMode="pin"
                app:srcCompat="@android:drawable/stat_notify_chat" />

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

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:scrollbars="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:scrollbarThumbVertical="@android:color/darker_gray"
        android:scrollbarSize="7dp"
        android:layout_height="match_parent"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

4 Answers

My guess is that you are loading the items in the RecyclerView too soon, before the CoordinatorLayout has finished measuring the AppbarLayout. This may happen if you have your list of items immediately available in your onViewCreated and you create and assign your adapter right away. I don't know how you setup your RecyclerView in your code, but I had this same problem and I solved it by using View.post(Runnable):

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val adapter = MyAdapter(viewModel.items)
    // replace:
    // recyclerView.adapter = adapter
    // with:
    view.post { recyclerView.adapter = adapter }
}

Also note that if you happened to use a subclass of ListAdapter, which works asynchronously from the main thread, infact you would likely not have had this issue.

Answered by devrocca on December 22, 2021

I ended up using the followiing, to detect last item scroll and notifyDataSetChanged(), that solves the issue :

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

        private boolean hasFixedLastItemNotVisible = false;

        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);

            if (!hasFixedLastItemNotVisible &&
                    !recyclerView.canScrollVertically(10) &&
                    newState==RecyclerView.SCROLL_STATE_IDLE) {
                hasFixedLastItemNotVisible = true;
                recyclerView.getAdapter().notifyDataSetChanged();
            }
        }
    });

Answered by FindOutIslamNow on December 22, 2021

when scrolling down recycleview....if you dont want a toolbar as recycleview is getting hidden behind toolbar....

use this--> app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"

so your collapsingtoolbarlayout code will be-->

 <com.google.android.material.appbar.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="350dp"
        app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
        app:contentScrim="?attr/colorPrimary"
        app:expandedTitleTextAppearance="@android:color/transparent"
        android:fitsSystemWindows="true"
        >

Answered by Wini on December 22, 2021

Tried your code multiple times with no luck. Finally found a workaround. Just add the height of view which you want to pin at the top as margin-bottom to the recyclerView keeping recyclerView's height as wrap_content.

For Ex. If you want to pin your toolbar then add it's height as margin-bottom to the recycler view

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:scrollbars="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:scrollbarThumbVertical="@android:color/darker_gray"
        android:scrollbarSize="7dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="?attr/actionBarSize"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

Hope this solves your problem.

Answered by Parag Pawar on December 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP