ListView 使用技巧

当需要指定ListView具体显示的Item时,可以通过如下代码来实现:

mListView.setSelection(position);

但这个方法类似scrollTo,是瞬间完成的移动。除此之外,还可以使用如下代码来实现平滑移动。

mListView.smoothScrollToPosition(position);
mListView.smoothScrollByOffset(offset);
mListView.smoothScrollBy(distance, duration);

ListView滑动监听

ListView的滑动监听,是ListView中最重要的技巧,很多重写的ListView,基本上都是在滑动事件的处理上下功夫,通过判断滑动事件进行不同的逻辑处理。而为了更加精确地监听滑动事件,开发者通常还需要使用GestureDetector手势识别、VelocityTracker滑动速度检测等辅助类来完成更好的监听。一般有两种监听方式,一种是通过OnTouchListener来实现监听,另一种是使用OnScrollListener来实现监听。

OnTouchListener
通过ACTION_DOWN、ACTION_MOVE、ACTION_UP这三个事件发生时的坐标,就可以根据坐标判断用户滑动的方向,并在不同的事件中进行相应的逻辑处理,代码如下:

        mListView.setOnTouchListener(new View.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;
            }
        });

OnScrollListener

OnScrollListener是AbsListView中的监听事件,它封装了很多与ListView相关的信息,使用也更加灵活。

        mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            private int lastVisibleItemPosition;//上次第一个可视的Item的ID

            /**
             * 当用户没有做手指抛动的状态时,这个方法只会回调2次,否则会回调3次,差别就是手指抛动的这个状态。
             * 通常情况下,我们会在这个方法中通过不同的状态来设置一些标志Flag,来区分不同的滑动状态,供其它
             * 方法处理。
             * @param view
             * @param scrollState
             */
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                switch (scrollState) {
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        //滑动停止时
                        Log.d("Test", "SCROLL_STATE_IDLE");
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        //正在滚动
                        Log.d("Test", "SCROLL_STATE_TOUCH_SCROLL");
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                        //手指抛动时,即手指用力滑动,在离开后ListView由于惯性继续滑动的状态
                        Log.d("Test", "SCROLL_STATE_FLING");
                        break;
                }
            }

            /**
             * 该方法在ListView滚动时会一直回调,通过该方法的后3个参数,可以很方便地进行一些判断
             * @param view
             * @param firstVisibleItem 当前能看见的第一个Item的ID(从0开始)
             * @param visibleItemCount 当前看见的Item总数(包括没有显示完整的Item)
             * @param totalItemCount 整个ListView的Item总数
             */
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                //滚动时一直调用
                Log.d("Test", "onScroll");

                //判断是否滚动到最后一行
                if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {

                }

                //判断滚动的方向
                if (firstVisibleItem > lastVisibleItemPosition) {
                    //上滑
                } else if (firstVisibleItem < lastVisibleItemPosition) {
                    //下滑
                }
                lastVisibleItemPosition = firstVisibleItem;
            }
        });

另外,ListView也给我们提供了一些封装的方法来获得当前可视的Item的位置信息:

        //获取可视区域内最后一个Item的id
        mListView.getLastVisiblePosition();
        //获取可视区域内第一个Item的id
        mListView.getFirstVisiblePosition();

具有弹性的ListView
我们在查看ListView的源代码时可以发现,ListView中有一个控制滑动到边缘的处理方法,如下所示:

protected boolean overScrollBy(int deltaX, int deltaY,
            int scrollX, int scrollY,
            int scrollRangeX, int scrollRangeY,
            int maxOverScrollX, int maxOverScrollY,
            boolean isTouchEvent)

注意参数:maxOverScrollY,注释中写道——Number of pixels to overscroll by in either direction along the Y axis。由此可以发现,虽然它的默认值是0,但其实只要修改这个参数的值,就可以让ListView具有弹性了。代码如下:

package com.example.huangfei.myapplication;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.ListView;

/**
 * Created by huangfeihong on 2016/5/4.
 * 具有弹性的ListView
 */
public class FlexibleListView extends ListView {

    private int mMaxOverDistance = 50;
    private Context mContext;

    public FlexibleListView(Context context) {
        super(context);
        mContext = context;
        init();
    }

    public FlexibleListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init();
    }

    public FlexibleListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        init();
    }

    //让不同分辨率设备的弹性距离基本一致
    private void init() {
        DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
        float density = metrics.density;
        mMaxOverDistance = (int) (density * mMaxOverDistance);
    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxOverDistance, isTouchEvent);
    }
}

参考与:http://blog.csdn.net/tw19911005/article/details/51308242

你可能感兴趣的:(ListView 使用技巧)