How to implement endless list with RecyclerView? How to implement endless list with RecyclerView? android android

How to implement endless list with RecyclerView?


Thanks to @Kushal and this is how I implemented it

private boolean loading = true;int pastVisiblesItems, visibleItemCount, totalItemCount;mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {    @Override    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {        if (dy > 0) { //check for scroll down            visibleItemCount = mLayoutManager.getChildCount();            totalItemCount = mLayoutManager.getItemCount();            pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();            if (loading) {                if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {                    loading = false;                    Log.v("...", "Last Item Wow !");                    // Do pagination.. i.e. fetch new data                    loading = true;                }            }        }    }});

Don't forget to add

LinearLayoutManager mLayoutManager;mLayoutManager = new LinearLayoutManager(this);mRecyclerView.setLayoutManager(mLayoutManager);


Make these variables.

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

Set on Scroll for recycler view.

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {    @Override    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {        super.onScrolled(recyclerView, dx, dy);        visibleItemCount = mRecyclerView.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            Log.i("Yaeye!", "end called");            // Do something            loading = true;        }    }});

Note : Make sure you are using LinearLayoutManager as layout manager for RecyclerView.

LinearLayoutManager mLayoutManager;mLayoutManager = new LinearLayoutManager(this);mRecyclerView.setLayoutManager(mLayoutManager);

and for a grid

GridLayoutManager mLayoutManager;mLayoutManager = new GridLayoutManager(getActivity(), spanCount);mRecyclerView.setLayoutManager(mLayoutManager);

Have fun with your endless scrolls !! ^.^

Update : mRecyclerView.setOnScrollListener() is deprecated just replace with mRecyclerView.addOnScrollListener() and the warning will be gone! You can read more from this SO question.

Since Android now officially support Kotlin, here is an update for the same -

Make OnScrollListener

class OnScrollListener(val layoutManager: LinearLayoutManager, val adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>, val dataList: MutableList<Int>) : RecyclerView.OnScrollListener() {    var previousTotal = 0    var loading = true    val visibleThreshold = 10    var firstVisibleItem = 0    var visibleItemCount = 0    var totalItemCount = 0    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {        super.onScrolled(recyclerView, dx, dy)        visibleItemCount = recyclerView.childCount        totalItemCount = layoutManager.itemCount        firstVisibleItem = layoutManager.findFirstVisibleItemPosition()        if (loading) {            if (totalItemCount > previousTotal) {                loading = false                previousTotal = totalItemCount            }        }        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {            val initialSize = dataList.size            updateDataList(dataList)            val updatedSize = dataList.size            recyclerView.post { adapter.notifyItemRangeInserted(initialSize, updatedSize) }            loading = true        }    }}

and add it to your RecyclerView like this

recyclerView.addOnScrollListener(OnScrollListener(layoutManager, adapter, dataList))

For a full code example, feel free to refer this Github repo.


For those who only want to get notified when the last item is totally shown, you can use View.canScrollVertically().

Here is my implementation:

public abstract class OnVerticalScrollListener        extends RecyclerView.OnScrollListener {    @Override    public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {        if (!recyclerView.canScrollVertically(-1)) {            onScrolledToTop();        } else if (!recyclerView.canScrollVertically(1)) {            onScrolledToBottom();        } else if (dy < 0) {            onScrolledUp();        } else if (dy > 0) {            onScrolledDown();        }    }    public void onScrolledUp() {}    public void onScrolledDown() {}    public void onScrolledToTop() {}    public void onScrolledToBottom() {}}

Note: You can use recyclerView.getLayoutManager().canScrollVertically() if you want to support API < 14.