检测ListView何时到达底部 - onScroll()或onScrollStateChanged()?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检测ListView何时到达底部 - onScroll()或onScrollStateChanged()?相关的知识,希望对你有一定的参考价值。
这似乎是一个有很多答案的问题;但是,我找不到一个通用的方法。我试图在达到底部时向ListView
添加数据;使用AsyncTask
从Internet检索数据。 ListView
已经附加了一个适配器。
因此,为了找到实现这一目标的好方法,我得出了两种不同的方法。
- 第一个,
onScrollStateChanged()
方法,基本上与this页面相关。但是,它使用的参数在实际API中没有对应关系。与此同时,this链接使用正确的API,但我不知道是否以正确的方式。我尝试了两个链接中的第一个,但它有点像meh。调试应用程序,diff
值变化很大,我不知道如何正确插入表达式。另外,我不知道如何修复我可以开始检索数据的偏移量;我的意思是,我想执行代码而不是在我即将到达底部时,而是在我到达之前。此外,即使我们滚动到顶部,有时它也会被调用。 - 第二个是
onScroll()
方法,在this答案中使用,或者以不同的方式在this代码中使用。我尝试调整两个代码中的最后一个,但它会导致很多问题,即使我们没有到达列表的底部,也会加载数据。
那么,最好的方法是什么?何时以及为什么我更喜欢其中一个?在我的情况下,我应该使用哪两个?
答案
这是我建议的第三种方法的一些代码,我在自己的项目中使用它。我使用适配器的getView
方法来检测何时到达列表的末尾。
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
}
另一答案
您可以使用适配器检测列表视图何时滚动到底部,因为@darnmason已在上面接受的答案中完成,但我发现有时当列表滚动速度非常快时,getView方法可能无法完成处理最后一个位置在适配器的最后...也许是因为它仍然呈现一些较早的位置。
当我滚动到列表底部有时无法渲染时,这种恼人的效果导致一个淡入视图的按钮。
这是具有烦人效果的解决方案,原则上类似于@darnmason的解决方案:
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);
}
此解决方案检测列表何时滚动到底部以及何时滚动远离底部。
要消除恼人的效果,只需修改如下:
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);
}
现在像往常一样调用适配器,如下所示:
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();
}
}
以这种方式实现时,适配器在检测列表何时滚动到底部时非常有效。
所需要的只是列表中的一点合作!
以上是关于检测ListView何时到达底部 - onScroll()或onScrollStateChanged()?的主要内容,如果未能解决你的问题,请参考以下文章