Home » Android » android – RecyclerView Infinite Scroll listener being called twice

android – RecyclerView Infinite Scroll listener being called twice

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have a RecyclerView that im trying to implement an infinite scroll feature into. The issue is, the code inside the if statements in the OnScrolled method is being executed twice. Heres my current code:

public abstract class InfiniteScroll extends RecyclerView.OnScrollListener {

private LinearLayoutManager mLayoutManager;
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;

private int current_page = 1;

public InfiniteScroll(LinearLayoutManager layoutManager) {
    mLayoutManager = layoutManager;
}

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

    visibleItemCount = recyclerView.getChildCount();
    totalItemCount = mLayoutManager.getItemCount();
    firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

    if (loading) {
        if (totalItemCount > previousTotal) {
            loading = false;
            previousTotal = totalItemCount;
        }
    }
    if (!loading && (totalItemCount - visibleItemCount)
            <= (firstVisibleItem + visibleThreshold)) {
        // End has been reached

        // Do something
        current_page++;
        Log.d("moreitems", "why is this being called twice?");
        loadMore(current_page);

        loading = true;
    }
}

public abstract void loadMore(int current_page);
}

This code was posted as an answer to a separate SO question, and other examples seem to function similar, but I still get the loadMore() method executing twice when reaching the bottom of the RecyclerView, and im not sure why.

How to&Answers:

it’s getting called because when you loadMore items, onScrolled is called again.

This callback will also be called if visible item range changes after a layout calculation. In that case, dx and dy will be 0.

so you could check
if (!loading && dy>0)
as well

Answer:

Try this:

 public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
                totalItemCount = linearLayoutManager.getItemCount();
                lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
                if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                    loading = true;
                    // End has been reached
                    // Do something
                       current_page++;
                       Log.d("moreitems", "why is this being called twice?");
                       loadMore(current_page);

                }
            }

Answer:

I just met similar situation, while solution is quite different from the above answer.

In my case, I have a custom RecyclerViewFragment, which will set up RecyclerView at the beginning of data loading stuff. And I add a custom OnScrollListener at that set up method block.

My reason why OnScrollListener was called twice is, I accidently add two OnScrollListener to my RecyclerView. Thus these two listener will both listener to the “scroll to the end” action and do something for it.

So I just remove all the OnScrollListener for my RecyclerView before I call the set up method, to make sure that there will only be one OnScrollListener.

Hope this help.

Answer:

if (layoutManager.findLastCompletelyVisibleItemPosition() == 
recyclerAdapter.getItemCount() - 1) {
     //load more items code is here
}

This will work.