This seems a question with many answers already; however, I can\'t find a common approach to this.
I\'m trying to add data to a ListView
when the bottom is reac
Here's some code for my suggested third approach, which I use in my own projects. I use the adapter's getView
method to detect when the end of the list has been reached.
public View getView(int position, View convertView, ViewGroup parent) {
// handle recycling/creating/initializing view
if(reachedEndOfList(position)) loadMoreData();
return convertView;
}
private boolean reachedEndOfList(int position) {
// can check if close or exactly at the end
return position == getSize() - 1;
}
private void loadMoreData() {
// Perhaps set flag to indicate you're loading and check flag before proceeding with AsyncTask or whatever
}
You can use an adapter to detect when the listview has been scrolled to its bottom as @darnmason has done in the accepted answer above, but I discovered that sometimes when the list is scrolled very fast, the getView method might not finish processing the last position in the adapter last...maybe because it was still rendering some earlier position.
This annoying effect caused a button that was to fade into view when I scrolled to the bottom of the list to sometimes fail to render.
Here is the solution with the annoying effect, which in principle is similar to @darnmason's solution:
public abstract class MyAdapter extends BaseAdapter {
public View getView(int position, View convertView, ViewGroup parent) {
//your code for getView here...
if(position == this.getCount() - 1){
onScrollToBottom(position);
}
else{
onScrollAwayFromBottom(position);
}
return convertView;
}
public abstract void onScrollToBottom(int bottomIndex);
public abstract void onScrollAwayFromBottom(int currentIndex);
}
This solution detects when the list is scrolled to the bottom and when it is scrolled away from the bottom.
To eliminate the annoying effect, simply modify as follows:
public abstract class MyAdapter extends BaseAdapter {
public View getView(int position, View convertView, ViewGroup parent) {
//your code for getView here...
if(position == this.getCount() - 1){
onScrollToBottom(position);
}
else{
AdapterView adapterView = (AdapterView) parent;
int count = adapterView.getCount();
if(adapterView.getLastVisiblePosition() == count - 1){
//The adapter was faking it, it is already at the bottom!
onScrollToBottom(count - 1);
}
else {
//Honestly! The adapter is truly not at the bottom.
onScrollAwayFromBottom(position);
}
}
return convertView;
}
public abstract void onScrollToBottom(int bottomIndex);
public abstract void onScrollAwayFromBottom(int currentIndex);
}
Now call your adapter as you normally would, like this:
MyAdapter adapter = new MyAdapter(){
@Override
public void onScrollToBottom(int bottomIndex) {
/*loadMore is a button that fades into view when you are not at the bottom of the list so you can tap and load more data*/
loadMore.show();
}
@Override
public void onScrollAwayFromBottom(int currentIndex) {
/*loadMore is a button that fades out of view when you are not at the bottom of the list*/
loadMore.hide();
}
}
When implemented this way, the adapter becomes very efficient at detecting when the list has been scrolled to its bottom.
All it needed was a little cooperation from the list!