ListView的滑动监听,是ListView中最重要的技巧,很多重写的ListView,基本上都是在滑动事件的处理上下功夫,通过判断滑动事件进行不同的逻辑处理。而为了更加精确的监听滑动事件,通常还需要使用GestureDetector手势识别、VelocityTracker滑动速度监测等辅助类来完成更好的监听。下面我们来介绍两种监听ListView滑动事件的方法。
1、OnTouchListener
OnTouchListener是view中的监听事件,通过监听ACTION_DOWN 、ACTION_MOVE、 ACTION_UP这三个事件发生时的坐标,就可以根据坐标判断用户滑动的方向,并在不同的事件中进行相应的逻辑处理,这种方式的使用代码如下:
listView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { //触摸时操作 case MotionEvent.ACTION_DOWN: break; //移动时操作 case MotionEvent.ACTION_MOVE: break; //离开时操作 case MotionEvent.ACTION_UP: break; } return false; } });2、OnScrollListener
OnScrollListener是AbsListView中的监听事件,它封装了很多与Listview相关的信息,使用起来也更加灵活。首先来看一下OnScrollListener的一般使用方法,代码如下:
listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { //滑动停止时 case OnScrollListener.SCROLL_STATE_IDLE: break; //正在滚动 case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: break; //手指抛动时,即手指用力滑动,在离开后listview由于惯性继续滑动的状态 case OnScrollListener.SCROLL_STATE_FLING: break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //滑动时一直调用 } });当用户没有做手指抛动的状态时,OnScrollStateChanged()这个方法只会回调2次,否则会回调3次,差别就是手指抛动的这个状态。通常情况下,我们会在这个方法中通过不同的状态来设置一些标志flag,来区分不同的滑动状态,供其他方法处理。
onScroll()这个回调方法,它在ListView滚动时会一直回调,而方法中的后三个int类型的参数,则非常精确地显示了当前ListView滚动状态,这单个参数如下所示:
firstVisibleItem当前能看见的第一个item的id(从0开始)
visibleItemCount当前能看见的item总数
totalItemCount整个ListView的item总数
这里需要注意的是,当前能看见的item数,包括没有显示完整的item,即显示一小半的item也包括在内了。通过这几个参数可以很方便的进行一些判断,比如判断是否滚动到最后一行,就可以使用如下代码进行判断:
if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount >0){ //滚动到最后一行 }再比如,可以通过如下代码判断滚动的方向,代码如下所示:
if (firstVisibleItem > lastVisibleItemPosition) { //上滑 } else if (firstVisibleItem < lastVisibleItemPosition) { //下滑 }通过一个成员变量lastVisibleItemPosition来记录上次第一个可视的item的id并与当前可视item的id进行比较,即可知道当前滚动方向。
ListView也给我们提供了一些封装的方法来获得当前可视的item的位置等信息
//获取可视区域内最后一个item的id listView.getLastVisiblePosition(); //获取可视区域内第一个item的id listView.getFirstVisiblePosition();