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