Android 手势事件工具类GestureDetector和VelocityTracker

    Android提供了一些工具类,以便于快速判断手势事件的类型和进行相关处理。例如各种动作的判断(双击、长按等),例如计算滑动速度。这些当然可以在onTouchEvent(MotionEvent)中自己写逻辑进行处理,但借助工具类更简便。

1.手势检测器GestureDetector,可用于判断各种手势,双击、长按等。

示例代码和注释如下:

// 步骤1.创建一个监听回调

GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() {

    /*常用的回调方法*/

    //单击

    @Override

    public boolean onSingleTapConfirmed(MotionEvent e) {

        //......业务逻辑......

        return false;

    }

    //双击

    @Override

    public boolean onDoubleTap(MotionEvent e) {

        //......业务逻辑......

        return false;

    }

    //长按

    @Override

    public void onLongPress(MotionEvent e) {

        //......业务逻辑......

    }

    //滚动

    @Override

    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

        //......业务逻辑......

        return false;

    }

    //快速滑动

    @Override

    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        //......业务逻辑......

        return false;

    }

};

// 步骤2.创建一个检测器

final GestureDetector detector = new GestureDetector(this, listener);

//解决长按屏幕后无法拖动的问题(这行是《Android开发艺术探索》中建议)

detector.setIsLongpressEnabled(false);

// 步骤3.将事件对象传递给手势检测器GestureDetector。

// 可以在外部setOnTouchListener来获取MotionEvent对象,可在View类自己的onTouchEvent()中获取。

mTvTop.setOnTouchListener(new View.OnTouchListener() {

    @Override public boolean onTouch(View v, MotionEvent event) {

        //《Android开发艺术探索》中的建议是:

        //双击这类事件用GestureDetector来判断;

        //滑动这类事件结合MotionEvent的action类型,自己写逻辑来判断,。

        return detector.onTouchEvent(event);

    }

});

2.滑动速度检测:VelocityTracker(用于滑动速度检测)

简单原理:监测指定时间内,某个触摸点在x轴、y轴上滑动的像素数,正向滑动时,为正值;反向滑动时,为负值。

附:可通过ViewConfiguration来获取系统中一系列滑动相关的参数,例如能够触发滑动事件的最小滑动距离,系统中的最大滑动速率等。

VelocityTracker示例代码和注释如下:

​
public class VelocityTrackerActivity extends Activity {

    private VelocityTracker mVelocityTracker;

    private int mMaxVelocity;

    private int mPointerId;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mVelocityTracker = VelocityTracker.obtain();//步骤1:创建检测器对象

        //获取设备支持的最大滑动速率,单位:像素/s

        mMaxVelocity = ViewConfiguration.get(this).getMaximumFlingVelocity();

        //获取系统能够识别出的最小滑动距离,即 能够触发系统滑动事件的最小滑动距离。

        //有时候用户的手指在点击时有轻微的抖动,发生了极微小的距离,这时候用户并想滑动,也许只是想点击

        //如何区分用户是否想滑动呢,建议用系统给的这个值来判断,在不同的设备上这个值有时候是不同的。

        int touchSlop = ViewConfiguration.get(this).getScaledTouchSlop();

    }

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        final int action = event.getAction();

        mVelocityTracker.addMovement(event);//步骤2:添加被检测的事件

        final VelocityTracker verTracker = mVelocityTracker;

        switch (action) {

            case MotionEvent.ACTION_DOWN:

                //此时可能有多个触点,此处监控第一个触点的滑动速度

                mPointerId = event.getPointerId(0);

                break;

            case MotionEvent.ACTION_MOVE:

                //步骤3:指定时间内的滑动的像素数距离(正向滑动时,为正值;反向滑动时,为负值。)

                //此处设定本次监测的时间长度,单位ms

                //第二个参数值作用:当滑动速率大于第二个参数值时,将以第二个参数值来作为速率。

                verTracker.computeCurrentVelocity(1000, mMaxVelocity);

                //获取指定时间内,水平滑动、数值滑动的像素距离

                float velocityX = verTracker.getXVelocity(mPointerId);

                float velocityY = verTracker.getYVelocity(mPointerId);

                //计算滑动速度,单位:像素/s

                float speedX = velocityX;

                float speedY = velocityY;

                break;

            case MotionEvent.ACTION_UP:

                releaseVelocityTracker();//步骤4:监听结束后,释放监听器对象

                break;

            case MotionEvent.ACTION_CANCEL:

                releaseVelocityTracker();//步骤4:监听结束后,释放监听器对象

                break;

            default:

                break;

        }

        return super.onTouchEvent(event);

    }

    //释放VelocityTracker

    private void releaseVelocityTracker() {

        if(null != mVelocityTracker) {

            mVelocityTracker.clear();

            mVelocityTracker.recycle();

            mVelocityTracker = null;

        }

    }

}

​

猜你喜欢

转载自blog.csdn.net/u013914309/article/details/124594097