Android手势监测-GestureDector

来源:互联网 发布:程序员输入法 编辑:程序博客网 时间:2024/06/05 10:10

在自定义view的时候,我们通常通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,但是对于一些比较复杂的手势,我们如果自己去通过MotionEvent来自己判断的话会有一些复杂和不准确,所以Android为我们提供了GestureDector类来方便我们进行手势的监听处理.

GestureDector为我们提供了两个接口和一个静态外部类供我们去使用,分别是两个接口:OnGestureListener,OnDoubleTapListener,一个静态外部类:SimpleGestureListener.

我们先看一下OnGestureListener这个接口,下面我们看下implements这个接口的代码:

private class gestureListener implements GestureDetector.OnGestureListener{            // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发             public boolean onDown(MotionEvent e) {              Log.i("MyGesture", "onDown");                 Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT).show();                 return false;          }            /*            * 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发            * 注意和onDown()的区别,强调的是没有松开或者拖动的状态            *           * 而onDown也是由一个MotionEventACTION_DOWN触发的,但是他没有任何限制,          * 也就是说当用户点击的时候,首先MotionEventACTION_DOWN,onDown就会执行,          * 如果在按下的瞬间没有松开或者是拖动的时候onShowPress就会执行,如果是按下的时间超过瞬间          * (这块我也不太清楚瞬间的时间差是多少,一般情况下都会执行onShowPress),拖动了,就不执行onShowPress。          */          public void onShowPress(MotionEvent e) {              Log.i("MyGesture", "onShowPress");                 Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT).show();             }            // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发             ///轻击一下屏幕,立刻抬起来,才会有这个触发          //从名子也可以看出,一次单独的轻击抬起操作,当然,如果除了Down以外还有其它操作,那就不再算是Single操作了,所以这个事件 就不再响应          public boolean onSingleTapUp(MotionEvent e) {              Log.i("MyGesture", "onSingleTapUp");                 Toast.makeText(MainActivity.this, "onSingleTapUp", Toast.LENGTH_SHORT).show();                 return true;             }            // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发             public boolean onScroll(MotionEvent e1, MotionEvent e2,                  float distanceX, float distanceY) {              Log.i("MyGesture22", "onScroll:"+(e2.getX()-e1.getX()) +"   "+distanceX);                 Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_LONG).show();                               return true;             }            // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发             public void onLongPress(MotionEvent e) {               Log.i("MyGesture", "onLongPress");                  Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_LONG).show();             }            // 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发             public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,                  float velocityY) {              Log.i("MyGesture", "onFling");                 Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_LONG).show();                 return true;          }      };  
我们看到需要我们重写6个函数,下面我们分别看一下各个函数的调用顺序及特点:

1.onDown(MotionEvent e):用户按下屏幕就会触发.

2.onShowPress(MotionEvent e):如果用户按下屏幕后没有立即松开或拖动会调用此方法,事件调用顺序为onDown--->onShowPress.

3.onLongPress(MotionEvent e):如果用户按下屏幕后没有松开或拖动会调用此方法,事件调用顺序为onDown-->onShowPress-->onLongPress.

4.onSingleTapUp(MotionEvent e):如果用户按下屏幕后立即松开会调用此方法,如果按下之后还有其他操作没有立即松开则不会调用此操作(顾名思义:简单的点击一下,也就意味着没有其他多余的操作才会触发),如果点击一下快速抬起则事件调用顺序为onDown-->onSingleTapUp-->onSingleTapUpConfirmed,如果稍微慢点点击抬起则事件调用顺序为onDown-->onShowPress-->onSingleTapUp-->onSingleTapUpConfirmed.

5.onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY):用户按下屏幕后手指在屏幕上滑动会会调用此方法,但是一次滑动事件仅会调用一次.onFling()的四个参数分别为e1---第一个ACTION_DOWN的motionEvent,e2--第二个ACTION_UP的motionEvent,velocityX--X轴上的手指滑动速度,像素/秒,velocityY--Y轴上的手指滑动速度,像素/秒.事件调用顺序为onDown-->onScroll-->onScroll-->......-->onFling.

6.onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):用户按下屏幕后手指在屏幕上滑动会调用此方法,与onFling的区别是在一个滑动事件中onScroll会调用多次,参数中的后两个为滑动的距离而不是滑动的速度.onScroll的四个参数分别为e1---第一个ACTION_DOWN的motionEvent,e2--第二个ACTION_UP的motionEvent,distanceX--在X轴上滑动距离,distanceY--在Y轴上的滑动距离.事件调用顺序为onDown-->onScroll-->onScroll-->......-->onFling.

接下来看一下OnDoubleTapListener这个接口,下面是我们实现OnDoubleTapListener的代码:

private class onDoubleTapListener implementsGestureDetector.OnDoubleTapListener {/* * 用来判定该次点击是SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,如果只点击一次, * 系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap, * 然后触发SingleTapConfirmed事件。 */@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {// TODO Auto-generated method stubreturn false;}/*双击事件 */@Overridepublic boolean onDoubleTap(MotionEvent e) {// TODO Auto-generated method stubreturn false;}/*  * 双击间隔中发生的动作。指触发onDoubleTap以后,在双击之间发生的其它动作,包含down、up和move事件 * @MotionEvent e中包含了双击直接发生的其他动作. */@Overridepublic boolean onDoubleTapEvent(MotionEvent e) {// TODO Auto-generated method stubreturn false;}}
我们看到要重写3个函数,我们来分别看一下各个函数的调用时间及特点:

1.onSingleTapConfirmed():当用户按下屏幕后并快速抬起时调用并在之后短时间没有二次点击,主要是用来确认用户该次点击是onSingleTap而不是onDoubleTap.事件调用顺序为:onDownn-->onSingleTap-->onSingleTapConfirmed.

2.onDoubleTap():当用户双击屏幕时调用,如果用户触发了onDoubleTap则不会触发onSingleTapConfirmed.该事件调用顺序为:ondown-->onSingleTap-->onDoubleTap().

3.onDoubleTapEvent():当用户双击屏幕间,触发的触摸事件,包含down,up和move事件,事件封装在参数MotionEvent e中.

最后我们看一下SimpleGestureListener静态外部类,代码如下

private class simpleGestureListener extends GestureDetector.SimpleOnGestureListener{@Overridepublic boolean onSingleTapUp(MotionEvent e) {// TODO Auto-generated method stubreturn super.onSingleTapUp(e);}@Overridepublic void onLongPress(MotionEvent e) {// TODO Auto-generated method stubsuper.onLongPress(e);}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {// TODO Auto-generated method stubreturn super.onScroll(e1, e2, distanceX, distanceY);}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {// TODO Auto-generated method stubreturn super.onFling(e1, e2, velocityX, velocityY);}@Overridepublic void onShowPress(MotionEvent e) {// TODO Auto-generated method stubsuper.onShowPress(e);}@Overridepublic boolean onDown(MotionEvent e) {// TODO Auto-generated method stubreturn super.onDown(e);}@Overridepublic boolean onDoubleTap(MotionEvent e) {// TODO Auto-generated method stubreturn super.onDoubleTap(e);}@Overridepublic boolean onDoubleTapEvent(MotionEvent e) {// TODO Auto-generated method stubreturn super.onDoubleTapEvent(e);}@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {// TODO Auto-generated method stubreturn super.onSingleTapConfirmed(e);}}
基本就把我们之前介绍的7个方法拼在一起,并没有什么特别的地方,所以我们就看下GestureDector如何使用.

GestureDector的使用分为3步

1.新建一个GestureDector对象

GestureDetectormGestureDetector = new GestureDetector(new gestureListener());
2.实例化一个GestureDetector.OnGestureListener通过我们上面的三种方法

3.在onTouch()事件中声明将触摸事件交给GestureDector处理

/* * 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法, * 将捕捉到的MotionEvent交给GestureDetector 来分析是否有合适的callback函数来处理用户的手势 */@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubreturn mGestureDetector.onTouchEvent(event);}

0 0