2012-03-09 41 views
7

有没有办法确定listview是否向上或向下滚动?如何检测列表视图是在android中向上或向下滚动?

OnScrollListener在这种情况下帮不了我。

在此先感谢!

+0

究竟你想要什么?你可以解释更多... – 2012-03-09 06:35:27

+0

我想在列表滚动时制作一些代码,并在列表向下滚动时制作其他代码。因此,我想检测它是否滚动向上或向下 – dor506 2012-03-09 06:40:13

+3

请参阅http://stackoverflow.com/questions/6358428/implementation-of-onscrolllistener-to-detect-the-end-of-scrolling-in-a-listview – 2012-03-09 06:46:46

回答

12

这是一个简单的实现:

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; 

     } 
    }); 
+2

只有在顶层物品不再是第一个物品时才有用。如果您在相同的物品保留在顶部时来回滚动,则不会告诉您方向。 – AndroidDev 2015-05-26 11:56:14

4

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

首先,创建揭露保护法

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

然后,创建您的包装,并延长滚动型

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() {...}); 
+2

这似乎只是在你抛出列表时才被调用,它不会被重复调用。 – 2013-01-13 05:09:08

0

由一些菜鸟学生给出的解决方案是好的:你必须创建一个包装使用受保护的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; 
       } 
      } 
     } 
0
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; 
     } 
    }); 

这里基于最后一个可见项目我决定列表是否或进入上下

1

一个简单和工作方案。

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; 
     } 
+1

完美运作,谢谢! – error1337 2017-07-25 09:45:54

1

对他们来说,永远仍在寻找科特林一个答案,这适用于它

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() 
      } 
     } 

    }) 
} 

取消注释,使用另一种方法。

相关问题