概述
我们都知道,手指触摸屏幕时会产生一系列的事件,如手指刚按下会产生DOWN事件,移动产生MOVE事件,松开产生UP事件。为了与用户进行友好的交互,我们的程序往往需要检测这一系列的事件,从而将它们解释成一个既定的手势,最后做出准确的响应。例如,当用户用手指在屏幕上画出一个圆形,这将产生一些列的触摸事件DOWN-MOVE-MOVE-...UP,然后程序检测到这些事件后进行一定的分析,确定这是一个圆形手势,最后程序对这个手势(画圆)做出相应的操作,如亮屏。
这里涉及到两个问题:
- 如何获取触摸事件
- 如何检测手势并做出响应
第一点很好回答,用户触摸View产生事件会回调onTouchEvent方法,在这个方法中就可以获取所有的触摸事件。当然,具体是哪个View接收到这些事件,这与View的事件分发机制相关,由于本篇文章并不是讲这个的,所以就不详细解释了,不懂的小伙伴可以自行谷歌相应的文档进行学习。
至于第二点,就和本篇的主人公GestureDetector有着大大的关联了。检测手势是在获取触摸事件的基础上做的,因而也是在onTouchEvent中进行,通常情况下,这个检测手势的工作是由我们来做的,比如,我们判断到在很短的时间内连续接收到了两次DOWN事件,那么我们有理由认为这是一个双击操作。幸运的是,为了减少我们的工作量,谷歌提供了一个类专门用于检测手势,它自然就是GestureDetector了,这个类的使用非常简单,废话不多说,直接开搞。
使用
本篇文章中,我们使用GestureDetectorCompat这个类,它是GestureDetector的一个兼容类,位于V4包中,可以兼容到1.6版本。
第一步、实例化GestureDetectorCompat
detector = new GestureDetectorCompat(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d(TAG, "onSingleTapUp: ");
return super.onSingleTapUp(e);
}
@Override
public void onLongPress(MotionEvent e) {
Log.d(TAG, "onLongPress: ");
super.onLongPress(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.d(TAG, "onScroll: ");
tracer.computeCurrentVelocity(1000);
Log.d(TAG, "onScroll: " + tracer.getXVelocity() + ":" + tracer.getYVelocity());
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d(TAG, "onFling: ");
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public void onShowPress(MotionEvent e) {
Log.d(TAG, "onShowPress: ");
super.onShowPress(e);
}
@Override
public boolean onDown(MotionEvent e) {
Log.d(TAG, "onDown: ");
return super.onDown(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Log.d(TAG, "onDoubleTap: ");
return super.onDoubleTap(e);
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
Log.d(TAG, "onDoubleTapEvent: ");
return super.onDoubleTapEvent(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.d(TAG, "onSingleTapConfirmed: ");
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onContextClick(MotionEvent e) {
Log.d(TAG, "onContextClick: ");
return super.onContextClick(e);
}
});
构造方法中有两个参数,第一个是Context没啥好说的,第二个是一个监听。当GestureDetectorCompat检测到固定的手势后会回调相应的方法,我们也只需要在相应的方法中写代码逻辑就好了。
第二步、委托GestureDetector处理事件
@Override
public boolean onTouchEvent(MotionEvent event) {
detector.onTouchEvent(event);
return super.onTouchEvent(event);
}
总结
GestureDetector是一个辅助检测手势的类,使用起来非常简单,更重要的是它能检测出很多常用的手势操作,如点击、双击、滑动、Fling等。因此,善用这个类,可以让我们处理触摸事件更加的得心应手。