手势识别
当我们手指触摸手机屏幕的时候,会触发一系列的事件,比如down,up,move等,这也是我们在程序设计的过程中经常用到的手势,这些简单的手势使用覆写onTouchEvent()方法或者使用setOnTouchListener()来判断还是很容易的,可是如果我们想要更详细获取用户的手势,比如用户在X轴上滑动的距离或者速度,那么这些基本的方法就不是那么的合适了,还好谷歌给我们提供了一个类,也就是本文的主角--GestureDetector(手势识别器)。
GestureDetector的使用流程
- 实例化GestureDetector并为其注册监听器。
- 对需要进行手势识别的控件使用setOnTouchListener()或者覆写onTouchEvent()捕获Touch消息。
- 将Touch事件中获得的MotionEvent对象传递给GestureDetector,由GestureDetector处理Touch事件。
- GestureDetector处理后的消息通过监听器返回给用户。用户根据需要进行处理。
GestureDetector提供的监听器
- OnGestureListener : 处理单击类消息
- 单击:onDown(MotionEvent e)
- 抬起:onSingleTapUp(MotionEvent e)
- 短按:onShowPress(MotionEvent e)
- 长按:onLongPress(MotionEvent e)
- 滚动:onScroll(MotinEvent e1,MotinEvent e2,float distanceX,float distanceY)
- 滑动:onFling(MotionEvent e1,MotionEvent e2,float velocityX,float velocityY)
- OnDoubleTapListener : 处理双击类消息
- 双击:onDoubleTap(MotionEvent e)
- 双击按下和抬起各触发一次:onDoubleTapEvent(MotionEvent e)
- 单击确认:onSingleTapConfirmed(MotionEvent e) 单击一下以后,并没有点击第二下
SimpleOnGestureListener
谷歌不仅给我们提供了上面两个监听器,而且给我们提供了SimpleOnGestureListener这个类用于监听用户手势,这个类实现了上面两个监听器,并且覆写了所有方法(空方法),这样我们就可以自己编写一个类继承自SimpleOnGestureListener,按照自己的需要来覆写具体的方法,这也就是Simple的来由。
事件的触发条件
在测试事件触发之前,我们先使用下GestureDetector。
public class MainActivity extends Activity { private GestureDetector detector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_main); detector = new GestureDetector(this, new GestureListener()); } @Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); return super.onTouchEvent(event); } private class GestureListener extends SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { Log.v("x", "onDoubleTap"); return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.v("x", "onDoubleTapEvent"); return super.onDoubleTapEvent(e); } @Override public boolean onDown(MotionEvent e) { Log.v("x", "onDown"); return super.onDown(e); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.v("x", "onFling " + velocityX); return super.onFling(e1, e2, velocityX, velocityY); } @Override public void onLongPress(MotionEvent e) { Log.v("x", "onLongPress"); super.onLongPress(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.v("x", "onScroll " + " " + distanceX); return super.onScroll(e1, e2, distanceX, distanceY); } @Override public void onShowPress(MotionEvent e) { Log.v("x", "onShowPress"); super.onShowPress(e); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { Log.v("x", "onSingleTapConfirmed"); return super.onSingleTapConfirmed(e); } @Override public boolean onSingleTapUp(MotionEvent e) { Log.v("x", "onSingleTapUp"); return super.onSingleTapUp(e); } } }
这里我使用的是继承SimpleOnGestureListener并且覆写了全部的方法。
快速单击:onDown()->onSingleTapUp()->onSingleTapConfirmed()
单击以后停了一下再抬起:onDown()->onShowPress()->onSingleTapUp()->onSingleTapConfirmed()
长按:onDown()->onShowPress()->onLongPress()
双击:onDown()->onSingleTapUp()->onDoubleTap()->onDoubleTapEvent()->onDown()->onDoubleTapEvent()
按下滑动马上抬起:onDown()->onScroll()->onScroll()···->onScroll()->onFiling()
按下滑动保持一会再抬起:onDown()->onScroll()->onScroll()···->onScroll()
短按滑动:onDown()->onShowPress()->onScroll()···->onScroll()->onFiling() 长按以后滑动不会调用onScroll()和onFiling().
两个重要的方法
public boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
参数
e1 The first down motion event that started the scrolling.
e2 The move motion event that triggered the current onScroll.
distanceX The distance along the X axis that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
distanceY The distance along the Y axis that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
public boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
参数
e1 The first down motion event that started the fling.
e2 The move motion event that triggered the current onFling.
velocityX The velocity of this fling measured in pixels per second along the x axis.
velocityY The velocity of this fling measured in pixels per second along the y axis.
更多请查看:《缩放手势识别》