I have a grid view and want to update the items in grid view after the end of list is reached. To implement this i decided to use OnScrollListener. But the behavior of OnScrollListener is strange as it calls my method to update grid view many times..
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
if (firstVisibleItem + visibleItemCount >= totalItemCount) {
// End has been reached
// Call method to update
Log.i("CountShit", String.valueOf(firstVisibleItem) + " + "
+ String.valueOf(visibleItemCount) + " >= "
+ String.valueOf(totalItemCount));
}
}
});
and in my log the if conditioin is called many times as the onScrollListener keeps on listening the scroll i guess ..
09-29 14:06:10.338: I/CountShit(23640): 12 + 8 >= 20
09-29 14:06:10.353: I/CountShit(23640): 12 + 8 >= 20
09-29 14:06:10.369: I/CountShit(23640): 12 + 8 >= 20
09-29 14:06:10.385: I/CountShit(23640): 12 + 8 >= 20
09-29 14:06:10.400: I/CountShit(23640): 12 + 8 >= 20
09-29 14:06:10.424: I/CountShit(23640): 14 + 6 >= 20
09-29 14:06:10.439: I/CountShit(23640): 14 + 6 >= 20
09-29 14:06:10.455: I/CountShit(23640): 14 + 6 >= 20
09-29 14:06:10.470: I/CountShit(23640): 14 + 6 >= 20
09-29 14:06:10.486: I/CountShit(23640): 14 + 6 >= 20
Is there a way such that if i hit the end of list first time, my upate method is called.. and then if the user scrolls up or down or whatever the method should not be called again! (until i reach the end of my updated list ofcourse).
You are seeking an endless view. You have to create an endless scroll listener and apply it to GridView. Try below code;
Initialize GridView and apply adapter
final GridView g = (GridView) findViewById(R.id.myGrid);
g.setAdapter(new ImageAdapter(this));
EndlessScrollListener scrollListener=new EndlessScrollListener(g,new RefreshList() {
@Override
public void onRefresh(int pageNumber) {
System.out.println("On Refresh invoked..");
}
});
g.setOnScrollListener(scrollListener);
EndlessScrollListener
public class EndlessScrollListener implements OnScrollListener {
private GridView gridView;
private boolean isLoading;
private boolean hasMorePages;
private int pageNumber=0;
private RefreshList refreshList;
private boolean isRefreshing;
public EndlessScrollListener(GridView gridView,RefreshList refreshList) {
this.gridView = gridView;
this.isLoading = false;
this.hasMorePages = true;
this.refreshList=refreshList;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (gridView.getLastVisiblePosition() + 1 == totalItemCount && !isLoading) {
isLoading = true;
if (hasMorePages&&!isRefreshing) {
isRefreshing=true;
refreshList.onRefresh(pageNumber);
}
} else {
isLoading = false;
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void noMorePages() {
this.hasMorePages = false;
}
public void notifyMorePages(){
isRefreshing=false;
pageNumber=pageNumber+1;
}
public interface RefreshList {
public void onRefresh(int pageNumber);
}
}
Source
totalDataCount -> Variable which stores the total count of data your api gets you
previousTotal -> Variable which stores the previous total count. by default it is set to zero.
loading -> Boolean value set to false by default.
Declare all these variable in your activity and not in inner class(below)
This code will work below :-
public class EndlessScrollListenerUser implements OnScrollListener {
boolean loading = true;
public EndlessScrollListenerUser() {}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && lastInScreen==totalItemCount && totalDataCount>takeUser && (previousTotal)<totalDataCount) {
// Your API Call Goes Here after reaching end
loading = true;
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
}
I was able to solve the problem by adding some variables
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
and checking the following condition ..
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
pageCount++;
}
}
if (!loading
&& (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// End has been reached
Log.i("CountShit", String.valueOf(firstVisibleItem) + " + "
+ String.valueOf(visibleItemCount) + " >= "
+ String.valueOf(totalItemCount));
// call update method here
loading = true;
}
}
});