RecyclerView in CoordinatorLayout scrolls to top on data change

Viewed 302

I have a RecyclerView inside Viewpager, inside of CoordinatorLayout, and I am trying to make endless scrolling with a top bar, that scrolls to the top and disappears, leaving only the RecyclerView. Scrolling works perfectly, but whenever I update data in the RecyclerView itself (even something as simple as notifyItemChanged), the RecyclerView scrolls to the top of itself. The AppBarLayout stays hidden, so only the state of the RecyclerView is changing. Here is the layout itself:

<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:descendantFocusability="blocksDescendants"
    android:background="@color/main_bg_color">


    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_layout"
        android:layout_width="match_parent"
        android:background="@color/main_bg_color"
        android:layout_height="wrap_content"
        android:elevation="0dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <LinearLayout
            android:id="@+id/linearLayoutHeader"
            android:layout_width="match_parent"
            app:layout_scrollFlags="scroll"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <include
                android:id="@+id/includedLayout"
                layout="@layout/fragment_profile_before_viewpager" />

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabIconTint="@color/pink" />
        </LinearLayout>

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


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

</androidx.coordinatorlayout.widget.CoordinatorLayout>

And the layout of viewpager item (just a recyclerview):

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/gridRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

When first data arrives, I call notifyItemRangeInserted(0, newList.size()) on the adapter. When new data arrives, I call notifyItemRangeInserted(oldListSize + 1, newList.size());. However, nothing seems to help. I have tried:

  • Setting android:descendantFocusability="blocksDescendants" on the CoordinatorLayout, the ViewPager, and the RecyclerView itself.
  • Setting android:focusableInTouchMode="true" and "false" on the RecyclerView itself
  • Using notifyDataSetChanged to update the layout
  • Calling recyclerview.stopScroll() and recyclerview.stopNestedScroll()
  • Saving the state of the recycler before data change using onSaveInstanceState and onRestoreInstanceState
  • The issue also persists if there is no ViewPager, and just a RecyclerView below the AppBarLayout.
0 Answers
Related