【问题标题】:Detect when ListView has reached the bottom - onScroll() or onScrollStateChanged()?检测 ListView 何时到达底部 - onScroll() 或 onScrollStateChanged()?
【发布时间】:2015-03-26 11:24:42
【问题描述】:

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

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

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

那么,什么方法最好呢?什么时候以及为什么我应该选择其中一个? 在我的情况下,我应该使用这两者中的哪一个?

【问题讨论】:

  • 我发现最好使用适配器,在getView 中检查它是否是数据集中的最后一项,这意味着您已经滚动到列表的末尾。
  • @darnmason 当然可以,但是你用什么方法呢?
  • 您是否已经在使用自定义适配器?
  • 是的,我正在为我的列表视图使用自定义适配器
  • 所以你覆盖了getView,它传递了一个位置参数。根据适配器的大小检查位置,看看您是否已到达终点。

标签: android android-listview android-scroll


【解决方案1】:

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

【讨论】:

  • 感谢您的宝贵时间和回复。我想知道它在理论上是否正确:适配器应该/不应该做什么?当滚动到达底部时加载更多数据是它的工作吗?
  • 我个人认为是最适合它的地方。我还让适配器处理加载初始数据。此外,在加载数据时,我使用适配器通过增加适配器大小并使用不同的视图类型以不同方式呈现额外项目来显示带有加载图标的模拟项目。我觉得效果很好。
  • 感谢您的帮助,我认为您是对的。在接受您的回答之前等待其他一些回复。
  • 简单而完美的感谢人
  • 如何在 getview() 方法中调用我的主要活动类 loaddata() 方法??
【解决方案2】:

您可以使用适配器来检测列表视图何时滚动到其底部,正如@darnmason 在上面接受的答案中所做的那样,但我发现有时当列表滚动得非常快时,getView 方法可能无法完成处理适配器中的最后一个位置 last...可能是因为它仍在渲染某个较早的位置。

当我滚动到列表底部时,这个烦人的效果导致一个按钮淡入视野,有时无法呈现。

这里是有烦人效果的解决方案,原则上类似于@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();

            }

}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    相关资源
    最近更新 更多