android群英传笔记——ListView常用优化技巧(二、ListView的滑动监听)

来源:互联网 发布:淘宝蚕丝被真假 编辑:程序博客网 时间:2024/06/05 11:21
    ListView的滑动事件监听是ListView的最重要技巧,很多重写的ListView基本上都是在滑动事件的处理上下功夫,通过滑动事件进行不同的逻辑处理。这里主要介绍两种监听事件:onTouchListener和onScrollListener。为了更加精确地监听滑动事件,开发者通常还需要使用GestureDetector手势识别, VelocityTracker滑动速度检测等辅助类来完成更好的监听。

二、ListView 的滑动监听

1、onTouchListener

对于这个触摸事件监听之前就已经在事件的拦截机制里解释过,没了解过的读者可以点击进入事件的拦截机制来了解触摸事件。

以下是onTouchListener监听事件的实现代码:
mListView.setOnTouchListener(new View.onTouchListener(){      @Override     public boolean onTouch(View v, MotionEvent event) {         switch (event.getAction()){             case MotionEvent.ACTION_DOWN:                 // 触碰到时的操作                 Log.i(TAG, "onTouch: ACTION_DOWN!");                 break;             case MotionEvent.ACTION_MOVE:                 // 移动时的操作                 Log.i(TAG, "onTouch: ACTION_MOVE!");                 break;             case MotionEvent.ACTION_UP:                 // 离开时操作                 Log.i(TAG, "onTouch: ACTION_UP!");                 break;         }         return false;     }})

2、onScrollListener

这是AbsListView中的监听事件,它封装和许多和ListView相关的信息,使用起来更加灵活。首先来看一下OnScrollListener的一般使用方法,代码如下所示:
mListView.setOnScrollListener(new OnScrollListener(){      /**      * 监听滑动状态      * @param view 监听的控件      * @param scrollState 监听控件的状态      */     @Override     public void onScrollStateChanged(AbsListView view, int scrollState) {         switch (scrollState){             case OnListScrollListener.SCROLL_STATE_IDLE:                 // 滑动停止时                 Log.d(TAG, "onScrollStateChanged: scrollStop!");                 break;             case OnListScrollListener.SCROLL_STATE_TOUCH_SCROLL:                 // 正在滑动                 Log.d(TAG, "onScrollStateChanged: scrolling!");                 break;             case OnListScrollListener.SCROLL_STATE_FLING:                 // 手指抛动时,即手指用力滑动在离开后ListView由于惯性继续滑动                 Log.d(TAG, "onScrollStateChanged: scrollFling!");                 break;         }      }      /**        * 监听listView的滚动状态        * @param view 当前view        * @param firstVisibleItem 第一个显示的子项id        * @param visibleItemCount 可见的子项总数,包括显示部分的子项        * @param totalItemCount 子项的总数        */       @Override       public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {           // 滚动时一直调用           Log.d(TAG, "onScroll: onScroll!!!");           if(firstVisibleItem+visibleItemCount==totalItemCount && totalItemCount>0){               // 滚动到最后一行               Log.d(TAG, "onScroll: OnLastItem!");           }      }})
在onScrollListener中有两个方法:onScrollStateChanged和onScroll。先来看看onScrollStateChanged方法,它通过scrollState来决定其回调的次数,scrollState有以下三种模式:
  • OnScrollListener.SCROLL_STATE_IDLE:滚动停止时。
  • OnListScrollListener.SCROLL_STATE_TOUCH_SCROLL:正在滚动时。
  • OnListScrollListener.SCROLL_STATE_FLING:ListView的快速滑动造成惯性的状态。

当用户没有快速滑动,未造成惯性滑动,则此方法只调用两次,即:SCROLL_STATE_IDLE和SCROLL_STATE_TOUCH_SCROLL状态。否则三次,即三个状态都存在。通常通过设置flag来区分各个状态,共其他方法处理。

再来看看onScroll回调方法,这个回调方法只要ListView滑动则一直回调这个方法,之前笔者试过在此方法内加入一个Toast,后来发现这个Toast一直弹出,也就说明确实在ListView滑动的时候就调用此方法。如果在此方法内做操作,可能会多次重复调用,所以在使用前先想好是不是需要一直调用。当然,方法中的三个int类型参数,则非常精确的显示了当前ListView的滚动状态,这三个参数如下所示:
  • firstVisibleItem:当前能看到的第一个子项的ID(ID从0开始)。
  • visibleItemCount:当前能看到的子项总数。
  • totalItemCount:整个ListView的子项总数。

    注意:这里能看到的子项包括没有显示完整的子项,即便是只显示一小部分也算一个子项。通过以上参数可以很方法的做一些判断,举几个简单的例子:
if(firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0){    // 已经滚动到了最后一行}
再比如,通过如下代码可以判断滚动方向,代码如下所示:
if(firstVisibleItem > lastVisibleItemPosition){    // 上滑} else if(firstVisibleItem < lastVisibleItemPosition){    // 下滑}// 记录本次第一个可见子项的IDlastVisibleItemPosition = firstVisibleItem;
通过定义一个变量来进行记录上次第一个可见子项的ID并与当前第一个可见子项的ID进行比较,即可知道其滚动方向。当然,ListView也给我们提供了一些封装的方法获得当前可见的子项位置等信息:
// 获取可见区域内的最后一个子项的IDmListView.getLastVisiblePosition();// 获取可见区域内的第一个子项的IDmListView.getFirstVisiblePosition();

要想了解这个OnScrollListener,最好的方法就是在代码中添加log日志并打印出来。需要源码的读者可以点击这里进入上一篇获取下方的源码,其源码已经涵盖了本篇的事件监听。

感谢阅读,学习重在坚持,贵在坚持,那么下次再见。
0 0
原创粉丝点击