There is any way to implement endless scrolling to load more itens when i use SuperSLiM library?
Normally I'm used to use the LinearLayoutManager.findFirstVisibleItemPosition() method to help me to know when I need load more itens... but now, with linearlayout of SuperSLiM i can't use this.
How can i implement this feature?
In place of LinearLayoutManager,use LayoutManager of superslim. I had implemented it in one of demo project. Row code for that is,
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
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 LayoutManager mlayoutManager;
public EndlessRecyclerOnScrollListener(LayoutManager linearLayoutManager) {
this.mlayoutManager = layoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mlayoutManager.getItemCount();
firstVisibleItem = mlayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something here
current_page++;
loading = true;
}
}
public abstract void onLoadMore(int current_page);
}
I hope this will help you. :)
Related
I have a recyclerview with a bottom tab bar below it I have tried to achieve this using lots of code snippets but the event just wont get called
This is how i am trying it, first i created a Listener and then used it in my fragment.
public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
public static String TAG = EndlessRecyclerViewScrollListener.class
.getSimpleName();
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;
private int current_page = 1;
private LinearLayoutManager mLinearLayoutManager;
public EndlessRecyclerViewScrollListener(
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);
}
this is th code i write in my fragment
rv_influencer.addOnScrollListener(new EndlessRecyclerViewScrollListener((linearLayoutManager)) {
#Override
public void onLoadMore(int current_page) {
page_no++;
getInfluencerData();
Toast.makeText(getActivity(), "Scroll", Toast.LENGTH_LONG).show();
}
});
I have implemented pagination using EndlessRecyclerOnScrollListener. At a particular scenario I have to reset the page number, so i have created resetValues() method. But I don't know how to call this method from activity class.
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 = 0; // 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,boolean isfromversion) {
this.mLinearLayoutManager = linearLayoutManager;
Log.e("isversionendless",isfromversion+"");
if(isfromversion)
{
resetValues();
}
}
#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 void resetValues(){
previousTotal = 0;
loading = true;
visibleThreshold = 1;
firstVisibleItem = 0;
visibleItemCount = 0;
totalItemCount = 0;
}
public abstract void onLoadMore(int current_page);
}
EndlessRecyclerOnScrollListener scrollListener=new EndlessRecyclerOnScrollListener(
mGridLayoutManager) {
#Override
public void onLoadMore(int current_page) {
// do somthing...
loadMoreData(current_page);
}
};
recyclerView.setOnScrollListener(scrollListener);
when you want to reset values then just simply call method as below.
scrollListener.resetValues();
This is how I am setting up recyclerview.
mRecyclerViewRides = (RecyclerView) findViewById(R.id.recyclerViewRides);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerViewRides.setHasFixedSize(true);
// use a linear layout manager
mLinearLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerViewRides.setLayoutManager(mLinearLayoutManager);
mRideListAdapter = new FindRideListAdapter(getApplicationContext(), mRecyclerViewRides, mRideDetailArrayList, mImageOptions, mImageLoader, this);
mRecyclerViewRides.setAdapter(mRideListAdapter);
mRecyclerViewRides.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLinearLayoutManager) {
#Override
public void onLoadMore(int current_page) {
Log.e(TAG,"Scroll Count ==> "+(++mIntScrollCount));
if(!flagFirstLoad) {
mOffset = mOffset + mLimit;
getRideList(mOffset, mLimit);
}
}
});
This is the code for endless recycler view scroll listner.
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 = 1; // 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;
}
/**
* function to reset values of the properties of this class to initial
*/
public void resetValues(){
previousTotal = 0;
loading = true;
visibleThreshold = 1;
firstVisibleItem = 0;
visibleItemCount = 0;
totalItemCount = 0;
}
#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);}
So now whenever i scroll to bottom of the list onLoadMore() gets called twice and even intialy when i call getRideList() for the first time onScroll is getting invoked. I don't understand why?
Updated my support library and its working fine now.
I have a RecyclerView that im trying to implement an infinite scroll feature into. The issue is, the code inside the if statements in the OnScrolled method is being executed twice. Heres my current code:
public abstract class InfiniteScroll extends RecyclerView.OnScrollListener {
private LinearLayoutManager mLayoutManager;
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;
private int current_page = 1;
public InfiniteScroll(LinearLayoutManager layoutManager) {
mLayoutManager = layoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
current_page++;
Log.d("moreitems", "why is this being called twice?");
loadMore(current_page);
loading = true;
}
}
public abstract void loadMore(int current_page);
}
This code was posted as an answer to a separate SO question, and other examples seem to function similar, but I still get the loadMore() method executing twice when reaching the bottom of the RecyclerView, and im not sure why.
it's getting called because when you loadMore items, onScrolled is called again.
This callback will also be called if visible item range changes after a layout calculation. In that case, dx and dy will be 0.
so you could check
if (!loading && dy>0)
as well
Try this:
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
loading = true;
// End has been reached
// Do something
current_page++;
Log.d("moreitems", "why is this being called twice?");
loadMore(current_page);
}
}
I just met similar situation, while solution is quite different from the above answer.
In my case, I have a custom RecyclerViewFragment, which will set up RecyclerView at the beginning of data loading stuff. And I add a custom OnScrollListener at that set up method block.
My reason why OnScrollListener was called twice is, I accidently add two OnScrollListener to my RecyclerView. Thus these two listener will both listener to the "scroll to the end" action and do something for it.
So I just remove all the OnScrollListener for my RecyclerView before I call the set up method, to make sure that there will only be one OnScrollListener.
Hope this help.
if (layoutManager.findLastCompletelyVisibleItemPosition() ==
recyclerAdapter.getItemCount() - 1) {
//load more items code is here
}
This will work.
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"