【问题标题】:How to detect if a listview is scrolling up or down in android?如何检测列表视图在android中是向上还是向下滚动?
【发布时间】:2012-03-26 15:45:55
【问题描述】:

有没有办法识别列表视图是向上滚动还是向下滚动?

OnScrollListener 在这种情况下对我没有帮助。

提前致谢!

【问题讨论】:

  • 您到底想要什么?你能解释更多吗...
  • 我想在列表向上滚动时编写一些代码,并在列表向下滚动时编写其他代码。因此,我想检测它是向上还是向下滚动

标签: android listview scroll


【解决方案1】:

这是一个简单的实现:

lv.setOnScrollListener(new OnScrollListener() {

        private int mLastFirstVisibleItem;

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState){}

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {

            if(mLastFirstVisibleItem < firstVisibleItem){
                // Scrolling down
            }
            if(mLastFirstVisibleItem > firstVisibleItem){
                // scrolling up
            }
            mLastFirstVisibleItem = firstVisibleItem;
        }
    });

【讨论】:

  • 仅当顶部项目不再是第一项时才有用。如果您在同一项目保持在顶部时来回滚动,则不会告诉您方向。
  • 当项目高度较大时,这并不完美。
  • @VahidNajafi 那么,当列表视图较大并且项目高度较大时,有什么方法?
【解决方案2】:

ScrollViews 中有一个方法可以报告卷轴的移动。它被称为onScrollChanged()。但是,它被声明为受保护,因此您必须创建一个包装类来获得访问权限。该方法的使用方法请查看android docs。

首先,创建一个接口来暴露受保护的方法

public interface OnScrollListener {
void onScrollChanged(int x, int y, int oldx, int oldy);
}

然后,创建你的包装器并扩展 ScrollView

public class ReportingScrollView extends ScrollView {
private OnScrollListener onScrollListener = null;

public ReportingScrollView(Context context) {
    super(context);
}

public ReportingScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public ReportingScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public void setOnScrollListener(OnScrollListener onScrollListener) {
    this.onScrollListener = onScrollListener;
}

@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
    super.onScrollChanged(x, y, oldx, oldy);
    if (onScrollListener != null) {
        onScrollListener.onScrollChanged(x, y, oldx, oldy);
    }
}
}

最后,像自定义视图一样将它包含在您的 XML 布局中,并像往常一样附加侦听器。

<your.package.ReportingScrollView />

scrollingandtrolling.setOnScrollListener(new OnScrollListener() {...});

【讨论】:

  • 这个好像是在你甩列表的时候才调用的,不是重复调用的。
【解决方案3】:

对于那些还在为 kotlin 寻找答案的人来说,这适用于它

MainListView.setOnScrollListener(object :AbsListView.OnScrollListener {
     // var VisibleItem: Int = 0
      override fun onScroll(p0: AbsListView?, FirstVisibleItem: Int, i2: Int, i3: Int) {
      /*   
      if(VisibleItem < FirstVisibleItem)
      {
      Toast.makeText(applicationContext,"Scrolling Down",Toast.LENGTH_SHORT).show()
          fab.hide()
      }
      if(VisibleItem >FirstVisibleItem)
      {
          fab.show()
          Toast.makeText(applicationContext,"Scrolling Up",Toast.LENGTH_SHORT).show()
      }
          VisibleItem=FirstVisibleItem;
  */
      }
      override fun onScrollStateChanged(p0: AbsListView?, p1: Int) {
          if (p1 == 1) {
              fab.hide()
          } else {
              fab.show()
          }
      }

  })
}

取消注释以使用替代方法。

【讨论】:

    【解决方案4】:

    一个简单而有效的解决方案。

    private int lastPosition = -1;
    
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
            {
                if(lastPosition == firstVisibleItem)
                {
                    return;
                }
    
                if(firstVisibleItem > lastPosition)
                {
                    Logger.print("Going Down");
                }
                else
                {
                    Logger.print("Going Up");
                }
    
                lastPosition = firstVisibleItem;
            }
    

    【讨论】:

      【解决方案5】:

      Some Noob Student 给出的解决方案很好:您必须创建一个包装器才能使用受保护的 onScrollChanged(int x, int y, int oldx, int oldy) 方法,该方法比标准 AbsListView.OnScrollListener 更频繁地触发.onScrollStateChanged(AbsListView view, int scrollState).

      不幸的是,无论我如何滚动,onScrollChanged() 始终返回 0 作为参数,并且似乎仅在滚动结束时才检测到,到达列表的顶部或底部。

      所以我使用下面的代码来检测滚动的正确方向:它使用第一个可见项目的 getTop(),但也使用它的位置来了解第一个项目何时不再可见;在此项目转换期间,滚动方向由项目位置本身给出。

              @Override
              public void onScrollChanged(int x, int y, int oldx, int oldy) {
      
                  if(listView.getChildAt(0) != null) {
                      int scrollingDir = NO_SCROLLING;
                      int firstChildTop = listView.getChildAt(0).getTop();
      
                      if (listView.getFirstVisiblePosition() == mLastFirstVisiblePosition) {
                          if (mLastFirstChildTop < firstChildTop) {
                              //Scrolling DOWN
                              scrollingDir = SCROLLING_DOWN;
                          } else if (mLastFirstChildTop > firstChildTop) {
                              //Scrolling UP
                              scrollingDir = SCROLLING_UP;
                          }
                      } else if(listView.getFirstVisiblePosition() > mLastFirstVisiblePosition) {
                          //Scrolling UP
                          scrollingDir = SCROLLING_UP;
                      } else {
                          //Scrolling DOWN
                          scrollingDir = SCROLLING_DOWN;
                      }
                      mLastFirstVisiblePosition = listView.getFirstVisiblePosition();
                      mLastFirstChildTop = firstChildTop;
      
                      switch(scrollingDir) {
                          case SCROLLING_DOWN:
                              //Your DOWN scrolling code here
                              break;
      
                          case SCROLLING_UP:
                              //Your UP scrolling code here
                              break;
      
                          default:
                          case NO_SCROLLING:
                              break;
                      }
                  }
              }
      

      【讨论】:

        【解决方案6】:
        list.setOnScrollListener(new OnScrollListener() {
                int last_item;
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
        
                }
        
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem,
                        int visibleItemCount, int totalItemCount) {
                    if(last_item<firstVisibleItem+visibleItemCount-1){
                        System.out.println("List is scrolling upwards");
                    }
                    else if(last_item>firstVisibleItem+visibleItemCount-1){
                        System.out.println("List is scrolling downwards");
                    }
                     last_item = firstVisibleItem+visibleItemCount-1;
                }
            });
        

        这里根据最后一个可见项目,我决定列表是上升还是下降

        【讨论】:

          猜你喜欢
          • 2015-02-02
          • 2019-06-30
          • 1970-01-01
          • 2017-09-02
          • 2023-03-06
          • 1970-01-01
          • 2016-03-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多