how to implement pagination based on upper and lower limit on recyclerview - android

I'm working with recycler view and i am working on social module like facebook and want to implement Pagination on recycler view This is my method defination
** public void getUserSharedTimeline(int userId, int lowerLimit,int upperLimit )**
Now first time I send 0 to 10 to server and get ten records. and then I call it like this.
mRecyclerView.addOnScrollListener(new EndlessScrollListener(mLayoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount) {
getUserSharedTimeline(Utilities.UserTypeId,totalItemsCount,totalItemsCount+10);
}
});
On first call
it works and get me 10 to 20 records
Then on second call it gets 20 to 21 records
and after that it's stop scrolling and do not load more data even records are more than thousand.
The pagination is also done on server side and I can't request more than 10 records at a time.
Here is my class for pagination. I checked many tutorials but in vain. Please help me in this issue.
package com.intelmanager.ithash.intelmanager.ui;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.widget.AbsListView;
public abstract class EndlessScrollListener extends RecyclerView.OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 10;
// 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 EndlessScrollListener(RecyclerView.LayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
}
public EndlessScrollListener(GridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
public EndlessScrollListener(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 LinearLayoutManager) {
lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
} else if (mLayoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// 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);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
}

Related

EndlessOnScrollListener with RecyclerView

I follow this code to add endlessscroll for RecyclerView, it's work but when i scroll to the end, data load done and the list back up to top over and over again, scroll to the end, data load done and back up to top of the list. How to fix it? I really don't understand why, please help me, thank you very much.
Here, this is my code:
public abstract class EndlessOnScrollListener 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 EndlessOnScrollListener(LinearLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
}
public EndlessOnScrollListener(GridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
public EndlessOnScrollListener(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 LinearLayoutManager) {
lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
} else if (mLayoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// 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);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
}
private void setUpRecyclerViewVideo() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
rvVideo.setLayoutManager(linearLayoutManager);
rvVideo.setHasFixedSize(true);
rvVideo.setItemAnimator(new DefaultItemAnimator());
rvVideo.setAdapter(adapterVideo);
swipe_container.setRefreshing(false);
adapterVideo.notifyDataSetChanged();
if (isLoadMore){
rvVideo.addOnScrollListener(new EndlessOnScrollListener(linearLayoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount) {
fetchVideoDataFromServer("https://afternoon-beyond-44158.herokuapp.com/all/" + Constants.PAGE_SIZE_5 + "/" + totalItemsCount);
}
});
}
It is example for EndlessOnScrollView .

How to avoid binding of all items in Recyclerview, when it is inside NestedScrollview?

I have a Recyclerview, inside NestedScrollview. Recyclerview is having different item types that need to load dynamically,But all items in recyclerview are binding together when it is inside nested scroll. How can I avoid this? I don't need any pagination. I just want to minimize the view rendering.
Try this code:
import android.support.v4.widget.NestedScrollView;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public abstract class RecyclerViewByNestedScrollListener implements NestedScrollView.OnScrollChangeListener {
// 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;
// The minimum amount of pixels to have below your current scroll position
// before loading more.
private int visibleThresholdDistance = 500;
RecyclerView.LayoutManager mLayoutManager;
public RecyclerViewByNestedScrollListener(RecyclerView.LayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
}
#Override
public void onScrollChange(NestedScrollView scrollView, int x, int y, int oldx, int oldy) {
// We take the last son in the scrollview
View view = scrollView.getChildAt(scrollView.getChildCount() - 1);
int distanceToEnd = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));
int totalItemCount = mLayoutManager.getItemCount();
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// 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 && distanceToEnd <= visibleThresholdDistance) {
currentPage++;
onLoadMore(currentPage, totalItemCount);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
}
and then use NestedScrollView as parent of your recyclerView. Then in code do like this:
LinearLayoutManager layoutManager=new LinearLayoutManager(this);
NestedScrollView mScrNested=(NestedScrollView)findViewById(R.id.nestedScrollView);
mScrNested.setOnScrollChangeListener(new RecyclerViewByNestedScrollListener(layoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount) {
//load next page of your recyclerView
}
});
As you see at above, you must set load more of your recyclerview with nestedScorllView. Otherwise your data load at once and your view has lagged.
All of this problem is because recyclerView not work properly inside ScrollView.
** Updated answer **
Try using Handler like below for delaying add each item to your recyclerview:
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
yourList.add(newItem);
adapter.notifyDataSetChanged();
}
},random);//set your delay time here like 2000 for two seconds delay

How do you process large amount of data to be render?

In the below code example, 50 thousand Customer needs to be loaded using ListView or RecyclerView
// current process, I am using pagination to load items
List<Customer> customers = mCustomerModule.get(limit, offset);
mAdapter.addItems(customer);
Couchbase lite version 1.3
The retrieval of customers is made by views
Problem
Slow when scrolling, when reached a high amount of customers
Question
Does my pagination process slow down the performance?
Couchbase lite 1.3 views are really slow?
Goal
Improve performance
Smoothen viewing of customer list
What you are looking for is called Endless Scrolling. Take a look at this article that describe the problem and present the solution for both: with ListView and with RecyclerView:
Endless Scrolling with AdapterViews and RecyclerView
UPDATE
Here's how to implement it using a RecyclerView (info taken from above link)
Use this code as is that would be the EndlessRecyclerViewScrollListener, that will react to scrolls on the RecyclerView. So you need to set the addOnScrollListener of your RecyclerView to an instance of this class:
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 the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// 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);
}
Inside the mentioned onLoadMore method, load additional items into the adapter either by sending out a network request or by loading from another source.
For example:
scrollListener = new EndlessRecyclerViewScrollListener(linearLayoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
// Triggered only when new data needs to be appended to the list
// Add whatever code is needed to append new items to the bottom of the list
loadNextDataFromApi(page);
}
};
// Adds the scroll listener to RecyclerView
rvItems.addOnScrollListener(scrollListener);
When you intend to perform a new search, make sure to clear the existing contents from the list and notify the adapter the contents have changed as soon as possible. Make sure also to reset the state of the EndlessRecyclerViewScrollListener with the resetState method:
// 1. First, clear the array of data
listOfItems.clear();
// 2. Notify the adapter of the update
recyclerAdapterOfItems.notifyDataSetChanged(); // or notifyItemRangeRemoved
// 3. Reset endless scroll listener when performing a new search
scrollListener.resetState();

onLoadMoreListener won't stop loading - RecyclerView - Android

I have a user feed where user's posts will be displayed if the current user is following them, at the moment I have the loadMoreListener working fine in regards to it loading the next batch of images when they get to the bottom of the RecyclerView. But, when I reach the last item (the feeds only shows 50 posts) in the List it'll attempt to load more and cause an OutOfMemoryException. I've restricted the size of the list in the adapter, but at the minute I can't seem to work out when the user has hit the very bottom to stop the progress from displaying and to stop the OnLoadMoreListener from triggering. This is what I have tried so far:
Adapter Constructor:
public RecyclerViewAdapterAllFeeds(Context context,
final ArrayList<AllFeedsDataModel> previousPostsList, final boolean profile, RecyclerView recyclerView, final ProgressBar progressBar) {
this.context = context;
this.previousPostsList = previousPostsList;
this.profile = profile;
if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager)recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
progressBar.setVisibility(View.VISIBLE);
if (getItemCount() > LOADED_POSTS - 2) {
totalItemCount = getItemCount();
// total_posts = getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (lastVisibleItem <= TOTAL_POSTS) {
if (!loading && totalItemCount <= (lastVisibleItem)) {
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
loading = true;
}
}
}
}
});
}
}
onLoadMoreListener
adapter = new RecyclerViewAdapterAllFeeds(getActivity(), latestUpdatesList, false, recyclerView, progressBar);
recyclerView.setAdapter(adapter);// set adapter on recyclerview
adapter.setOnLoadMoreListener(new RecyclerViewAdapterAllFeeds.OnLoadMoreListener() {
#Override
public void onLoadMore() {
refreshCount++;
populateRecyclerView(true, refreshCount);
adapter.update(updatesList);
adapter.setLoaded();
System.out.println("load");
}
});
adapter.notifyDataSetChanged();// Notify the adapter
progressBar.setIndeterminate(false);
progressBar.setVisibility(View.INVISIBLE);
My question is how can I stop it loading if the total posts is less than that of the restrictions or to know when the final item is visible?
First create EndlessRecyclerViewScrollListener.java:
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
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 LinearLayoutManager) {
lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
} else if (mLayoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// 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);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
}
And then implement in this way:
recyclerView.addOnScrollListener(new EndlessRecyclerViewScrollListener(recyclerView.getLayoutManager()) {
#Override
public void onLoadMore(int page, int totalItemsCount) {
//TODO Add logic for load more posts or show message if posts is ended.
}
});
Check out the code which I use for endless scroll:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// if (BuildConfig.DEBUG)
// Log.d(TAG, "onScrolled: [x, y]=[" + dx + ", " + dy + "], count=[" + recyclerView.getLayoutManager().getChildCount() + ", " + recyclerView.getLayoutManager().getItemCount() + ", " + ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition() + "]");
if (hasMoreRequest) {
if (dy > 0) { //check for scroll down
checkForMoreLoad();
}
}
}
});
private void checkForMoreLoad() {
final Handler handler = new Handler();
Runnable checkForMoreData = new Runnable() {
#Override
public void run() {
if (null != recyclerView) {
int visibleItemCount = recyclerView.getLayoutManager().getChildCount();
int totalItemCount = recyclerView.getLayoutManager().getItemCount();
int pastVisibleItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
onScrollToLoad(visibleItemCount, pastVisibleItems, totalItemCount);
}
}
};
handler.postDelayed(checkForMoreData, 100);
}
private void onScrollToLoad(int visibleItemCount, int pastVisibleItems, int totalItemCount) {
if ((visibleItemCount + pastVisibleItems) + 4 >= totalItemCount && hasMoreRequest) {
if (BuildConfig.DEBUG)
Log.d(TAG, "onScroll lastInScreen - so load more");
startNetworkCall(page + 1);
}
}
And after data from API, if there is more data after that I will again call checkForMoreLoad().
The line which has (visibleItemCount + pastVisibleItems) + 4 in onScrollToLoad() has 4 in it. It is for starting API before hand of reaching end of the scroll.

Implementing Endless RecyclerView

I want to implement an endless RecyclerView but so far all the implementations and tutorials I have come across describe loading data off a server then loading it or dynamically adding elements using a loop.
In my case, I already have a large ArrayList containing the data I want to display in the RecyclerView.
What I need is to say, display the first 10 items of the array, and on loading more, display the next batch of 10.
This could achieve your goal.
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
private int previousTotal = 0; // The total number of items in the dataset after the last load
private boolean loading = true; // True if we are still waiting for the last set of data to load.
private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
int firstVisibleItem, visibleItemCount, totalItemCount;
private int current_page = 1;
private LinearLayoutManager mLinearLayoutManager;
public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
current_page++;
onLoadMore(current_page);
loading = true;
}
}
public abstract void onLoadMore(int current_page);
}
And sample activity
public class SampleActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
#Override
public void onLoadMore(int current_page) {
// do something...
}
});
}
}
Edit: See here: Endless Scrolling with AdapterViews
You can use this Endless Adapter
It is generic, you give it (You model, Recycler.ViewHolder)
You can set the adapter either show loading or not.
Have Listeners to check when loading finished, and when loading starts.
You can check also the sample for more info
Try using:
recyclerView.addOnScrollListener (recyclerViewOnScrollListener);
private RecyclerView.OnScrollListener recyclerViewOnScrollListener = new RecyclerView.OnScrollListener () {
private final String LOG_TAG = "PAGINATION_";
boolean isIdle;
#Override
public void onScrollStateChanged (RecyclerView recyclerView, int newState) {
try {
super.onScrollStateChanged (recyclerView, newState);
isIdle = (newState == RecyclerView.SCROLL_STATE_IDLE);
}
catch (Exception e) {
e.printStackTrace ();
}
}
#Override
public void onScrolled (RecyclerView recyclerView, int dx, int dy) {
firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition ();
super.onScrolled (recyclerView, dx, dy);
if (!isIdle dy > 0) {
int totalItems = yourList.size()();
totalItemCount = layoutManager.getItemCount ();
visibleItemCount = layoutManager.getChildCount ();
Log.i (LOG_TAG, "Max: " + totalItems + ", Total: " + totalItemCount + ", Previous Total: " + previousTotal + ", Visible: " + visibleItemCount + ", First: " + firstVisibleItemPosition);
if (isLoading) {
if (totalItemCount != previousTotal) {
isLoading = false;
previousTotal = totalItemCount;
}
}
isLastPage = (totalItemCount >= totalItems);
Log.i (LOG_TAG, "DETAILS: currentPage: " + currentPage + ", isLoading: " + isLoading + ", isLast: " + isLastPage);
if (!isLoading && !isLastPage) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0 && totalItems >= (currentPage * PAGE_LIMIT) && totalItems > totalItemCount) {
if (totalItems > (currentPage * PAGE_LIMIT)) {
currentPage = (totalItemCount / PAGE_LIMIT) + 1;
isLoading = true;
//load more data using currentPage and PAGE_LIMIT
}
}
}
}
previousTotal = totalItemCount;
}
catch (Exception e) {
e.printStackTrace ();
}
}
}
}
};
try using this class it help me alot :
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 the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// 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);
}
reference :
https://gist.github.com/nesquena/d09dc68ff07e845cc622
https://guides.codepath.com/android/Endless-Scrolling-with-AdapterViews-and-RecyclerView

Categories

Resources