Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement endless list with RecyclerView?

I would like to change ListView to RecyclerView. I want to use the onScroll of the OnScrollListener in RecyclerView to determine if a user scrolled to the end of the list.

How do I know if a user scrolls to the end of the list so that I can fetch new data from a REST service?

like image 617
erdna Avatar asked Oct 24 '14 07:10

erdna


People also ask

Can you display a scrolling list of items in a RecyclerView?

To be able to scroll through a vertical list of items that is longer than the screen, you need to add a vertical scrollbar. Inside RecyclerView , add an android:scrollbars attribute set to vertical .

How can show all items in RecyclerView without scrolling?

How can show all items in RecyclerView without scrolling? In RecyclerView use android:nestedSrollingEnabled="false" and use NestedScrollView as a parent Scroll View.

How many times onCreateViewHolder is called in RecyclerView?

By default it have 5. you can increase as per your need. Save this answer.


2 Answers

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); 
like image 109
Abdulaziz Noor Avatar answered Sep 22 '22 20:09

Abdulaziz Noor


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.

like image 34
Kushal Sharma Avatar answered Sep 26 '22 20:09

Kushal Sharma