13

I want to implement pagination with recyclerView, for this I add addOnScrollListener to the recyclerView but I am having trouble with RecyclerView.OnScrollListener not working when I set rvGridExplore.setNestedScrollingEnabled(false);

But when I remove rvGridExplore.setNestedScrollingEnabled(false); it is working fine, I don't know how to handle this.

Here is code:

rvGridExplore = (RecyclerView) view.findViewById(R.id.rvGridExplore);
        final GridLayoutManager glm = new GridLayoutManager(context,2);
       // rvGridExplore.setNestedScrollingEnabled(false);
        rvGridExplore.setLayoutManager(glm);

       // final int visibleItemCount,totalCount,pastVisibleItems;
        rvGridExplore.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                Log.v("scrollll","state changed");
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) {
                    int totalCount = glm.getItemCount();
                    int visibleItemCount = glm.getChildCount();
                    int pastVisibleItems = glm.findFirstVisibleItemPosition();
                    if (loading) {
                        if ((visibleItemCount + pastVisibleItems) >= totalCount) {
                            Log.v("scroll","scrolled"+pastVisibleItems);
                        }
                    }

                }
            }
        });
user3678528
  • 1,692
  • 2
  • 18
  • 21
Adnan Ali
  • 752
  • 1
  • 8
  • 20

6 Answers6

6

This question may be old, but to help others who stumbled upon this problem, i would like to share what i did. I had to implement onScroll Listener to recyclerview to load data from server and to make some UI changes. And also needed swipeRefresh Layout for refreshing data.

This was my xml file structure,

-RelativeLayout

 -SwipeRefreshLayout

  -NestedScrollView

   -LinearLayout(Vertical)

    -Multiple views required

After this, to detect up and down scrolling i implemented setOnScrollListener to the NestedScrollView.

Normal usage of SwipeRefreshLayout to refresh data.

And to load more data i implemented the logic inside onScrollListener of NestedScrollingView.

if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()))  {

    // Load More Data
}
Garg's
  • 2,526
  • 1
  • 31
  • 44
m.n Aswin
  • 119
  • 1
  • 7
5

Do add setOnScrollChangeListner to your NestedScrollView

 nestedScrollview.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()))  {
               if(loading)
                onClick();
               loading=false;
            }
        }
    });

after loading data from server set boolean loading=true.

Harish Reddy
  • 730
  • 7
  • 18
2

If you are recyclerView is embedded in any of the NestedScrollView, then you are supposed to attach the onScrollListener to NestedScrollView.

This will work!

if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
    final GridLayoutManager gridLayoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
    nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()))  {
                totalItemCount = gridLayoutManager.getItemCount();
                lastVisibleItem = gridLayoutManager.findLastVisibleItemPosition();
                if (!loading
                        && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                    // End has been reached
                    // Do something
                    if (onLoadMoreListener != null) {
                        onLoadMoreListener.onLoadMore();
                    }
                    loading = true;
                }
            }
        }
    });
}
Sreekant Shenoy
  • 619
  • 6
  • 15
1

You said in a comment to your question "
it is under NestedScrollView which is under coordinator layout, if i remove this, Toolbar is not scrolling up". This is a mistake.

I have found that you cannot have it both ways, the CoordinatorLayout behaviour breaks when you have a RecyclerView inside a NestedScrollView to which you've added the behaviour. You need to use one or the other.

When you have a RecyclerView inside a NestedScrollView it will work as long as you set RecyclerView.setNestedScrollingEnabled(false), but as you found out this means that the OnScrollListener is not called.

The only way for all components to work correctly is to remove the NestedScrollView, make sure you do not set nesting scroll to false and work from there. Otherwise the RecyclerView.OnScrollListener events will not fire correctly.

r3flss ExlUtr
  • 650
  • 6
  • 16
0

Step 1 : Create EndlessRecyclerOnScrollListener

public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {

    public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();

    // use your LayoutManager instead
    private LinearLayoutManager llm;

    public EndlessRecyclerOnScrollListener(LinearLayoutManager sglm) {
        this.llm = llm;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        if (!recyclerView.canScrollVertically(1)) {
            onScrolledToEnd();
        }
    }

    public abstract void onScrolledToEnd();
}

Step 2: Apply scroll listener to recycler view.

recyclerview.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
            @Override
            public void onScrolledToEnd() {
                Log.e("Position", "Last item reached");
                if (loadMore == true) {
                    // put your Load more code
                    // add 10 by 10 to tempList then notify changing in data
                }
            }
        });
Vishal Patoliya ツ
  • 2,840
  • 2
  • 17
  • 42
  • 1
    you mean i put the child class in constructor it will work ? please read the question properly. my Listener is not working because of setNestedScrollingEnabled(false); – Adnan Ali Jul 04 '16 at 08:42
  • than why you are putting nestedScrollingEnabled(false) ?? – Vishal Patoliya ツ Jul 04 '16 at 08:43
  • see the comments on question – Adnan Ali Jul 04 '16 at 08:43
  • i also do a pagination with this code like same situation as you – Vishal Patoliya ツ Jul 04 '16 at 08:44
  • first put your layout.xml if you want proper answer!! – Vishal Patoliya ツ Jul 04 '16 at 08:45
  • @VishalPatoliyaツ It is not working in the case of StaggeredGridLayoutManager ...Do u have any idea about it..Please help – Ravindra Kushwaha Jan 30 '17 at 14:07
  • @VishalPatoliyaツ .. I want to load more functionality in my Straggered recyclview...Yet now i am facing the problem is that.. i am not getting the event to identify that user is reached at the bottom of the list OR not...Could u plz help me on this... I have also asked the question on SO..My question link is this http://stackoverflow.com/questions/41930139/staggered-gridview-recycleview-with-load-more-functionality – Ravindra Kushwaha Jan 31 '17 at 10:22
0

remove the nested scroll view use linear or relative layout instead of it as root element then you can write recyclerview.setNestedScrollEnabled(false);