Jatin
Jatin

Reputation: 1670

Pagination not work for the RecyclerView within NestedScrollView

How to implement pagination of recyclerview that is within NestedScrollView?

Upvotes: 28

Views: 20749

Answers (4)

Alireza Barakati
Alireza Barakati

Reputation: 1084

I had the same problem and based on Android documentation:

Never add a RecyclerView or ListView to a scroll view. Doing so results in poor user interface performance and a poor user experience.

I solved my problem using bellow code:

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appbar_layout"
    android:background="@color/white"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        app:titleEnabled="false">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <!-- Put here elements that you need above the recycler view -->

        </LinearLayout>

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

</com.google.android.material.appbar.AppBarLayout>
<!-- RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:nestedScrollingEnabled="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:scrollbars="vertical"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Upvotes: 0

jmarkstar
jmarkstar

Reputation: 1335

I could get the solution setting OnScrollChangeListener in the nestedScrollView.

The field isLoading should be changed everytime you load the items, for example if you are using retrofit. You could set it as true before It start running and as false when you get the response or the failure.

The field isLastPage should be changed everytime you get items and check if this page was the last one.

I'm using kotlin.

private var isLoading = false

private var isLastPage = false

nestedScrollView.setOnScrollChangeListener { v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int ->

            val nestedScrollView = checkNotNull(v){
                return@setOnScrollChangeListener
            }

            val lastChild = nestedScrollView.getChildAt(nestedScrollView.childCount - 1)

            if (lastChild != null) {

                if ((scrollY >= (lastChild.measuredHeight - nestedScrollView.measuredHeight)) && scrollY > oldScrollY && !isLoading && !isLastPage) {

                    //get more items
                }
            }
        }

And of course you need to set the field isNestedScrollingEnabled as false

myRecyclerView.isNestedScrollingEnabled = false

Upvotes: 3

shahid17june
shahid17june

Reputation: 1577

if you are using Kotlin your code will be looks like

 scroll?.viewTreeObserver?.addOnScrollChangedListener {
        val view = scroll.getChildAt(scroll.childCount - 1)
        Timber.d("Count==============${scroll.childCount}")

        val diff = view.bottom - (scroll.height + scroll.scrollY)
        Timber.d("diff==============$diff")

        if (diff == 0) {
            //your api call to fetch data
        }
    }

and last but the not the least set RecyclerView scrolling false

 ViewCompat.setNestedScrollingEnabled(recyclerView, false)

Upvotes: 9

Vidhi Dave
Vidhi Dave

Reputation: 5684

Follow this steps :

1. Set nested scrolling enabled false of recycler view.

recyclerView.setNestedScrollingEnabled(false);

2. Add scroll listner to nested scrollview.

 mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
           @Override
           public void onScrollChanged()
           {
                    View view = (View)mScrollView.getChildAt(mScrollView.getChildCount() - 1);

                    int diff = (view.getBottom() - (mScrollView.getHeight() + mScrollView
                                    .getScrollY()));

                    if (diff == 0) {
                       // your pagination code
                    }
           }
  });

Upvotes: 57

Related Questions