-
-
Save rogerhu/d041b6467536842aa986 to your computer and use it in GitHub Desktop.
public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener { | |
// The minimum amount of items to have below your current scroll position | |
// before loading more. | |
private int visibleThreshold = 5; | |
// The current offset index of data you have loaded | |
private int currentPage = 0; | |
// The total number of items in the dataset after the last load | |
private int previousTotalItemCount = 0; | |
// True if we are still waiting for the last set of data to load. | |
private boolean loading = true; | |
// Sets the starting page index | |
private int startingPageIndex = 0; | |
RecyclerView.LayoutManager mLayoutManager; | |
public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) { | |
this.mLayoutManager = layoutManager; | |
} | |
public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) { | |
this.mLayoutManager = layoutManager; | |
visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); | |
} | |
public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) { | |
this.mLayoutManager = layoutManager; | |
visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); | |
} | |
public int getLastVisibleItem(int[] lastVisibleItemPositions) { | |
int maxSize = 0; | |
for (int i = 0; i < lastVisibleItemPositions.length; i++) { | |
if (i == 0) { | |
maxSize = lastVisibleItemPositions[i]; | |
} | |
else if (lastVisibleItemPositions[i] > maxSize) { | |
maxSize = lastVisibleItemPositions[i]; | |
} | |
} | |
return maxSize; | |
} | |
// This happens many times a second during a scroll, so be wary of the code you place here. | |
// We are given a few useful parameters to help us work out if we need to load some more data, | |
// but first we check if we are waiting for the previous load to finish. | |
@Override | |
public void onScrolled(RecyclerView view, int dx, int dy) { | |
int lastVisibleItemPosition = 0; | |
int totalItemCount = mLayoutManager.getItemCount(); | |
if (mLayoutManager instanceof StaggeredGridLayoutManager) { | |
int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null); | |
// get maximum element within the list | |
lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions); | |
} else if (mLayoutManager instanceof GridLayoutManager) { | |
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition(); | |
} else if (mLayoutManager instanceof LinearLayoutManager) { | |
lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition(); | |
} | |
// If it’s still loading, we check to see if the dataset count has | |
// changed, if so we conclude it has finished loading and update the current page | |
// number and total item count. | |
if (loading && (totalItemCount > previousTotalItemCount)) { | |
loading = false; | |
previousTotalItemCount = totalItemCount; | |
} | |
// If it isn’t currently loading, we check to see if we have breached | |
// the visibleThreshold and need to reload more data. | |
// If we do need to reload some more data, we execute onLoadMore to fetch the data. | |
// threshold should reflect how many total columns there are too | |
if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) { | |
currentPage++; | |
onLoadMore(currentPage, totalItemCount, view); | |
loading = true; | |
} | |
} | |
// Call this method whenever performing new searches | |
public void resetState() { | |
this.currentPage = this.startingPageIndex; | |
this.previousTotalItemCount = 0; | |
this.loading = true; | |
} | |
// Defines the process for actually loading more data based on page | |
public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view); | |
} |
fixed, thanks
It works fine for me but my list refresh with new data from the requested api ? How to fix it .!
It works fine for me but my list refresh with new data from the requested api ? How to fix it .!
you should append the previous data, and don't clear it @ham007
@rogerhu is one allowed to use the code above ? Is there any license this code is under (MIT, Apache ?)
No license =)
@rogerhu then is one allowed to use the above snippet in a project?
A new feature is necessary when user wants to force a getMore()
(e.g. when we refresh our feed in Instagram). If the server call fails, how to force another getMore()
? It seems a failed server call results in a 'fully fetched' situation and no more loading is allowed. If the code runs OK, this is my misconception.
This snippet always returns -1:
else if (mLayoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
}
I really don't know what the issue is...
There is bug with GridLayoutManager in line 50 .
If it is a GridLayoutManager it never called and always LinearLayoutManager choose
should be:
instead to