I have one RecyclerView
and I added list of data into the RecyclerView
. I wanted to add more data in list, when last RecyclerView
item is visible on screen. After that I want to make a web service call and update the RecyclerView
data. How can I achieve this?
Any suggestions?
There are several ways to accomplish this, but one way would be to use your adapter's onBindViewHolder
method:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position == mData.length - 1) {
// load more data here.
}
/// binding logic
}
When the bind method is called with the last position of your data source, this is a good indication that the last cell is about to be displayed and a good time to trigger a reload call. You might need to add additional safeguards to the condition to make sure you're not already loading more data, but this should help you get started.
Another option would involve editing your LayoutManager
. The idea here is to find the position of the last visible item. If that position is equal to the last item of your dataset, then you should trigger a reload. This call should be done in your LayourManager's
onLayoutChildren
& scrollVerticallyBy
(assuming you use vertical scroll) methods:
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
final int result = super.scrollVerticallyBy(dy, recycler, state);
if (findLastVisibleItemPosition() == mData.length - 1) {
loadMoreData();
}
return result;
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
if (findLastVisibleItemPosition() == mData.length - 1) {
loadMoreData();
}
}
Same as before, you'll need to make sure you don't trigger a data load more than once, since it's possible this condition will occur more than once.
Hope this helps!
If someone stumble across this post this is a quick and simple tutorial on how to do it:
All you need to do is:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = lm.getChildCount();
int totalItemCount = lm.getItemCount();
int firstVisibleItemPosition= lm.findFirstVisibleItemPosition();
// Load more if we have reach the end to the recyclerView
if ( (visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
});
Then your loadMoreItems() should look something like this:
private void loadMoreItems() {
// init offset=0 the frist time and increase the offset + the PAGE_SIZE when loading more items
queryOffset = queryOffset + PAGE_SIZE;
// HERE YOU LOAD the next batch of items
List<Items> newItems = loadItems(queryOffset, PAGE_SIZE);
if (newItems.size() > 0) {
items.addAll(newItems);
adapter.notifyDataSetChanged();
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolderholder, int position) {
if (!list.isEmpty() || list== null) {
if (position == (list.size() - 1)) {
// add new data (add data to list)
this.notifyDataSetChanged();
}
}
}