繁体   English   中英

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

[英]Detect when ListView has reached the bottom - onScroll() or onScrollStateChanged()?

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

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

  1. 第一个, onScrollStateChanged()方法,基本上与页面相关。 但是,它使用的参数在实际API中没有对应关系。 同时, 链接使用正确的API,但我不知道是否以正确的方式。 我尝试了两个链接中的第一个,但它有点像meh。 调试应用程序, diff值变化很大,我不知道如何正确地插入表达式。 另外,我不知道如何修复我可以开始检索数据的偏移量; 我的意思是,我想执行代码而不是在我即将到达底部时,而是在我到达之前。 此外,即使我们滚动到顶部,有时它也会被调用。
  2. 第二个是onScroll()方法,在答案中使用,或者以不同的方式在代码中使用。 我尝试调整两个代码中的最后一个,但它会导致很多问题,即使我们没有到达列表的底部,也会加载数据。

那么,最好的方法是什么? 何时以及为什么我更喜欢其中一个? 在我的情况下,我应该使用哪两个?

这是我建议的第三种方法的一些代码,我在自己的项目中使用它。 我使用适配器的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();

            }

}

以这种方式实现时,适配器在检测列表何时滚动到底部时非常有效。

所需要的只是列表中的一点合作!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM