I think my code is ok, but for some reason I have this error. This is my code:
recyclerView.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("...", "Last Item Wow !");
//Do pagination.. i.e. fetch new data
}
}
}
}
});
I have already imported android.support.v7.widget.LinearLayoutManager and decleared
private RecyclerView recyclerView;
private RecyclerView.LayoutManager mLayoutManager;
Because there is no method like findFirstVisibleItemPosition in RecyclerView.LayoutManager (See documentation). You need to use LinearLayoutManager to use findFirstVisibleItemPosition
Change your declaration from this
private RecyclerView.LayoutManager mLayoutManager
to this
private LinearLayoutManager mLayoutManager
Related
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();
}
}
}
}
});
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();
}
}
}
});
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"
I try implement staggered RecyclerView. I create Abstract onScroll RecyclerView Like this :
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int grid_column_count = context.getResources().getInteger(R.integer.grid_column_count);
StaggeredGridLayoutManager mLayoutManager = new StaggeredGridLayoutManager(grid_column_count, StaggeredGridLayoutManager.VERTICAL);
int visibleItemCount = recyclerView.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItemsGrid[] = new int[grid_column_count];
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItemsGrid)[0];
if ((visibleItemCount + firstVisibleItem ) >= totalItemCount
&& totalItemCount != 0) {
onLoadingMore();
}
}
protected abstract void onLoadingMore();
and I implenting by MainActity
//===============
recyclerview= (RecyclerView)rootView. findViewById(R.id.grid_view);
recyclerview.setHasFixedSize(true);
grid_column_count = getResources().getInteger(R.integer.grid_column_count);
mLayoutManager = new StaggeredGridLayoutManager(grid_column_count, StaggeredGridLayoutManager.VERTICAL);
recyclerview.setLayoutManager(mLayoutManager);
//=====================
recyclerview.addOnScrollListener(new HidingScrollListener(getActivity()) {
#Override
protected void onLoadingMore() {
if ( isFinishLoadingAwal
&& !isFinishMoreNews
&& adapter.getItemCount()> 0) {
getMoreNewsFromServer();
}
}
});
But I getting error in line :
firstVisibleItem = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItemsGrid)[0];
log :
Process: com.ad.kamardagang, PID: 23350
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.support.v7.widget.OrientationHelper.getStartAfterPadding()' on a null object reference
at android.support.v7.widget.StaggeredGridLayoutManager$Span.findOneVisibleChild(StaggeredGridLayoutManager.java:2337)
at android.support.v7.widget.StaggeredGridLayoutManager$Span.findFirstVisibleItemPosition(StaggeredGridLayoutManager.java:2313)
at android.support.v7.widget.StaggeredGridLayoutManager.findFirstVisibleItemPositions(StaggeredGridLayoutManager.java:826)
at com.ad.kamardagang.utils.HidingScrollListener.onScrolled(HidingScrollListener.java:90)
at android.support.v7.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:3674)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2824)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3011)
at android.view.View.layout(View.java:15671)
so how to fix it ? or any solution ?
sorry for my english.
I use this Mugen for endless scrolling for StaggeredGrid with RecyclerView.
Replace firstVisibleItem = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItemsGrid)[0]; with
firstVisibleItem = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition(); and try.
I'm trying to write a code for endless scroll on a recycler view. This is the snippet that gives me a compiler error:
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if ( (visibleItemCount+pastVisiblesItems) >= totalItemCount) {
Log.v("...", "Last Item Wow !");
}
And the declaration I've written before is:
mLayoutManager = new LinearLayoutManager(this);
And mLayoutManager is an object of class RecyclerView.LayoutManager
mLayoutManager is an object of class RecyclerView.LayoutManager is wrong, you should use android.support.v7.widget.LinearLayoutManager for mLayoutManager, so:
mLayoutManager = new LinearLayoutManager(this);
//above 'LinearLayoutManager' is from
//'android.support.v7.widget.LinearLayoutManager'
mRecyclerView.setLayoutManager(mLayoutManager);
then mLayoutManager.findFirstVisibleItemPosition(); call should be ok in onScrolled(...);.
Hope this help!