检测ListView何时到达底部 - onScroll()或onScrollStateChanged()?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检测ListView何时到达底部 - onScroll()或onScrollStateChanged()?相关的知识,希望对你有一定的参考价值。

这似乎是一个有很多答案的问题;但是,我找不到一个通用的方法。我试图在达到底部时向ListView添加数据;使用AsyncTask从Internet检索数据。 ListView已经附加了一个适配器。

因此,为了找到实现这一目标的好方法,我得出了两种不同的方法。

  1. 第一个,onScrollStateChanged()方法,基本上与this页面相关。但是,它使用的参数在实际API中没有对应关系。与此同时,this链接使用正确的API,但我不知道是否以正确的方式。我尝试了两个链接中的第一个,但它有点像meh。调试应用程序,diff值变化很大,我不知道如何正确插入表达式。另外,我不知道如何修复我可以开始检索数据的偏移量;我的意思是,我想执行代码而不是在我即将到达底部时,而是在我到达之前。此外,即使我们滚动到顶部,有时它也会被调用。
  2. 第二个是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()?的主要内容,如果未能解决你的问题,请参考以下文章

检测 RecyclerView 滚动时何时到达最底部位置

检测 UIScrollview 底部到达

检测UIScrollview底部到达

我如何知道用户何时到达 UITextView 中文本的末尾

Android - 我怎么知道gridview何时到达底部?

检测何时在 ListView 中滑动项目