如何检测一个列表视图在android中向上或向下滚动?
有没有一种方法来确定是否ListView正在向上或向下滚动?
在这种情况下,OnScrollListener不会帮助我。
提前致谢!
这是一个简单的实现:
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) { Log.i("SCROLLING DOWN","TRUE"); } if(mLastFirstVisibleItem>firstVisibleItem) { Log.i("SCROLLING UP","TRUE"); } mLastFirstVisibleItem=firstVisibleItem; } });
在ScrollViews
中有一个方法来报告ScrollViews
的移动。 它被称为onScrollChanged()
。 但是,它被声明为protected,因此您必须创建一个包装类来获取访问权限。 有关该方法的用法,请查看android文档。
首先,创建一个接口来公开受保护的方法
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() {...});
一个简单而有效的解决方案
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; }
对于他们还在寻找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() } } }) }
取消注释以使用替代方法。
一些Noob Student给出的解决方案是很好的:你必须创建一个包装来使用受保护的onScrollChanged(int x,int y,int oldx,int oldy)方法,这个方法通常被标准的AbsListView.OnScrollListener.onScrollStateChanged AbsListView视图,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; } } }
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; } });
这里基于最后一个可见的项目,我决定列表是否正在上升或下降