How to implement pagination in recycler listview. I have to show 10 items per page. Can any one tell me how to deal with this?
You can add a scroll listener on recycler view and call the next paginated api on following condition:
recyclerList.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int pastVisibleItems = mLayoutManager
.findFirstVisibleItemPosition();
int currentPos = pastVisibleItems + visibleItemCount;
if (currentPos >= totalItemCount) {
callNextApi();
}
}
}
});
Related
I'm trying to implement pagination using code below, and it work well with fragments, but when i implemented it in Nested Fragment it load all data (load first page and all next pages continuously). The problem is that my total items is 12 and visible in time is 3 but layoutManager.getChildCount() give me 12 same as total item (layoutManager.getItemCount()) so it start loading next pages continuously.
Here is oNScroll code :
public PaginationScrollListener(LinearLayoutManager layoutManager) {
this.layoutManager = layoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
if (!isLoading() && !isLastPage()) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0
&& totalItemCount >= getTotalPageCount()) {
loadMoreItems();
}
}
}
When scroll and request next pages :
recyclerView.addOnScrollListener(new PaginationScrollListener(layoutManager) {
#Override
protected void loadMoreItems() {
isLoading = true;
currentPage += 1;
// mocking network delay for API call
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
loadNextPage();
}
}, 1000);
}
#Override
public int getTotalPageCount() {
return TOTAL_PAGES;
}
#Override
public boolean isLastPage() {
return isLastPage;
}
#Override
public boolean isLoading() {
return isLoading;
}
});
change your scroll listener like below:
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(dy>0){ //if is scrolling vertically
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
if (!isLoading() && !isLastPage()) {
if (firstVisibleItemPosition + visibleItemCount >= totalItemCount) {
//make your request here
}
}
}});
I use the following code to implement the infinite scroll. but the problem is the onScroll() method keeps calling continuously and loading data falls to an endless loop. what am I missing here?
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
public int previousTotal = 0; // The total number of items in the dataSet after the last load
public boolean loading = true; // True if we are still waiting for the last set of data to load.
public int visibleThreshold = 0; // The minimum amount of items to have below your current scroll position before loading more.
int firstVisibleItem, visibleItemCount, totalItemCount;
public 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)) {
current_page++;
onLoadMore(current_page);
loading = true;
}
}
public abstract void onLoadMore(int current_page);
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
}
and in my activity:
endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(mLayoutManager) {
#Override
public void onLoadMore(int current_page) {
loadData()
}
};
mRecyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
This is how I did endless scrolling and it works perfect for me. Thanks...
private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
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("...", "We reach Last Item!");
// fetch new data here or whatever you want.
DoPagination();
}
}
}
}
});
I have a requirement to scroll Recyclerview in one page increments. Each page containing a grid of 3 by 3 items.
I have used GridLayoutManager to implement the grid, now I am trying to override the onScrolled() method to implement scroll by page. I want each horizontal scroll to display 3 items which represents 1 page.
Here is portion of my code
recyclerView = (RecyclerView) rootView.findViewById(R.id.sub_category_list_recyclerview);
recyclerView.setHasFixedSize(true);
gridLayoutManager = new GridLayoutManager(getContext(), rowCount, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(gridLayoutManager);
adapter = new SubCategoryGridLayoutAdapter(new ArrayList<SubCategoryViewItem>());
recyclerView.setAdapter(adapter);
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) {
int visibleItemCount = gridLayoutManager.getChildCount();
int totalItemCount = gridLayoutManager.getItemCount();
int pastVisiblesItems = gridLayoutManager.findFirstVisibleItemPosition();
int lastitemPos = gridLayoutManager.findLastVisibleItemPosition();
if (dx > 0) {
//Right Scrolling
int moreItems = lastitemPos + 9;
if (totalItemCount > moreItems){
gridLayoutManager.scrollToPositionWithOffset(moreItems, 0);
}else {
gridLayoutManager.scrollToPositionWithOffset(totalItemCount, 0);
}
}
if (dx < 0) {
//Left Scrolling
int lessItems = pastVisiblesItems + 9;
if (lessItems < totalItemCount){
gridLayoutManager.scrollToPositionWithOffset(lessItems, 0);
}else {
gridLayoutManager.scrollToPositionWithOffset(totalItemCount, 0);
};
}
}
});
For future reading of this question, in support library 25.1.0 was added PageSnapHelper (for simulation of ViewPager - only scrolling item by item) or LinearSnapHelper (moves to the item that is closest to the middle of RecycleView).
Usage is simple :
PagerSnapHelper().attachToRecyclerView(rvYourRecycleViewName)
I tried implementing addOnScrollListener() but this thing fetch data and loading the recycler view from the beginning every time.i want to load the data after the current position.Here is my sample code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_load, null);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
progressBar.setVisibility(View.VISIBLE);
myClickHandler();
business_rv = (RecyclerView) view.findViewById(R.id.business_rv);
business = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL,false);
business_rv.setHasFixedSize(true);
business_rv.setLayoutManager(business);
if (business_rv.getLayoutManager() instanceof LinearLayoutManager) {
business = (LinearLayoutManager) business_rv.getLayoutManager();
business_rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
UpdateRecyclerView(url);
}
});
}
return view;
}
what you need is endless recycler view ,which will load the data while scrolling . Here I have attached link for that implementation.
Follow this link
use this as
_recycler.addOnScrollListener(_recyclerViewOnScrollListener);
private RecyclerView.OnScrollListener recyclerViewOnScrollListener = 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 = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
if (!isLoading && !isLastPage) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0
&& totalItemCount >= PAGE_SIZE) {
loadMoreItems(++currentPage);
}
}
}
};
I have been searching for a while but can't find a solution to detect end of scroll of recycler view with grid layout manager. Using code below actually work, but it is for linear layout manager not for grid layout manager.
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int scrollState) {
final int treeshold = 0;
try {
if (scrollState == RecyclerView.SCROLL_STATE_IDLE) {
if (((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition() >= yourData.size()
- 1 - treeshold) {
//your load more logic
}
}
} catch (Exception e) {
}
}
The idea is that i want to implement load more function to my application, so i need to detect end of scroll.
Edit : maybe the problem not the grid view itself. I used com.tonicartos.superslim library to get sticky header view. I wonder that it might be the problem
Add a scroll listener to your RecyclerView like below:
int pastVisiblesItems, visibleItemCount, totalItemCount;
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView,
int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
//bottom of recyclerview
}
}
});
layoutmanager is your GridLayoutManager
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 currentPage = 1;
private RecyclerView.LayoutManager mLayoutManager;
private boolean isUseLinearLayoutManager;
private boolean isUseGridLayoutManager;
public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
this.mLayoutManager = linearLayoutManager;
isUseLinearLayoutManager = true;
}
public EndlessRecyclerOnScrollListener(GridLayoutManager gridLayoutManager) {
this.mLayoutManager = gridLayoutManager;
isUseGridLayoutManager = true;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
if(isUseLinearLayoutManager && mLayoutManager instanceof LinearLayoutManager){
firstVisibleItem = ((LinearLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
}
if(isUseGridLayoutManager && mLayoutManager instanceof GridLayoutManager){
firstVisibleItem = ((GridLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
}
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
currentPage++;
onLoadMore(currentPage);
loading = true;
}
}
public abstract void onLoadMore(int currentPage);
I just sent an email directly to Mr. Artos about this problem and got a reply:
"It likely won't work properly until the next version is finished. I wrote about it on my blog at http://www.tonicartos.com/2015/12/superslim-milestone-1_23.html?m=1"