-
-
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...
@rogerhu
Thanks your code :)
Does it mean that the "no license" you answered before can be freely modified and distributed?
There is bug with GridLayoutManager in line 50 .
If it is a GridLayoutManager it never called and always LinearLayoutManager choose
should be:
instead to