View的速度追踪和手势检测

View的速度追踪

Android中使用VelocityTracker用于追踪手指在滑动过程中的速度,包括水平和竖直方向的速度。
VelocityTracker的使用:
首先,在View的onTouchEvent方法中追踪当前单击事件的速度;

VelocityTracker velocityTracker=VelocityTracker.obtain();
velocityTracker.addMovement(event);

接着我们想要知道当前的滑动速度时,这个时候可以采用如下方式来获得:

velocityTracker.computeCurrentVelocity(1000);
int xVelocity=(int)velocityTracker.getXVelocity();
int yVelocity=(int)velocityTracker.getYVelocity();

注:

  • 获取速度之前必须先计算速度,即getXVelocity和getYVelocity这两个方法前必须按要调用computeCurrentVelocity方法。
    -这里的速度是指一段时间内手指所滑过的像素数,速度可以为负数。
    最后,当不需要使用它的时候,需要调用clear方法来重制并回收内存:
velocityTracker.clear();
velocityTracker.recycle();

View的手势检测

Andorid提供类GestureDetector来手势检测,用于辅助检测用户的单击、滑动、长按、双击等行为。
GestureDetector的使用:

GestureDetector mGestureDetector=new GestureDetector(this,new GestureDetector.onGestureListener(){
        public boolean onDown(MotionEvent e) {
            return false;
        }

        // 2. 用户轻触触摸屏,尚未松开或拖动
        public void onShowPress(MotionEvent e) {
            Log.i("MyGesture", "onShowPress");
        }

        // 3. 用户长按触摸屏
        public void onLongPress(MotionEvent e) {
            Log.i("MyGesture", "onLongPress");
        }

        // 4. 用户轻击屏幕后抬起
        public boolean onSingleTapUp(MotionEvent e) {
            Log.i("MyGesture", "onSingleTapUp");
            return true;
        }

        // 5. 用户按下触摸屏 & 拖动
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
            Log.i("MyGesture", "onScroll:");
            return true;
        }

        // 6. 用户按下触摸屏、快速移动后松开
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                               float velocityY) {
            Log.i("MyGesture", "onFling");
            return true;
        }
});

如果需要检测一个View的手势,则需要重写View的onTouch方法,将View的触屏事件交给GestureDetector来处理。

View.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            mGestureDetector.onTouchEvent(event);
            return true; // 注:返回true才能完整接收触摸事件
        }
    });

当需要检测某一个Activity的手势时,则需要重写Activity的dispatchTouchEvent.

@Override   
public boolean dispatchTouchEvent(MotionEvent ev) {
        mGestureDetector.onTouchEvent(ev); // 让GestureDetector响应触碰事件
        super.dispatchTouchEvent(ev); // 让Activity响应触碰事件
        return false;
}

这时候如果需要检测用户的单击和双击手势,则需要实现OnDoubleTapListener接口。

 mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
        // 1. 单击事件
        // 关于OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的区别
        // onSingleTapConfirmed:再次点击(即双击),则不会执行
        // onSingleTapUp:手抬起就会执行
        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.i("MyGesture", "onSingleTapConfirmed");
            return false;
        }

        // 2. 双击事件
        public boolean onDoubleTap(MotionEvent e) {
            Log.i("MyGesture", "onDoubleTap");
            return false;
        }
        // 3. 双击间隔中发生的动作
        // 指触发onDoubleTap后,在双击之间发生的其它动作,包含down、up和move事件;
        public boolean onDoubleTapEvent(MotionEvent e) {
            Log.i("MyGesture", "onDoubleTapEvent");
            return false;
        }
    });

最后,我们来讲讲SimpleOnGestureListener这个类,它是集成了上述两个接口的手势检测功能,与上述两个接口的区别主要有:

  • OnGestureListener和OnDoubleTapListener接口里的函数都是强制必须重写的
  • 而SimpleOnGestureListener类的函数则可根据需要选择性复写,因为SimpleOnGestureListener类本身已经实现了这两个接口的所有函数,只是里面全是空的而已

你可能感兴趣的:(View的速度追踪和手势检测)