Android手势识别

来源:互联网 发布:陀地驱魔人 知乎 编辑:程序博客网 时间:2024/04/28 09:23

       Android中的手势识别,无非是系统对触屏信息的一个包装处理结果。如果要实现手势识别功能,首先需要实现OnTouchListener接口,并设置setOnTouchListener,最后在重载的函数onTouch()中,将MotionEvent交给GestureDetector去处理,典型的方式是gestureDetector.onTouchEvent(motionEvent)。


        概括一下手势操作的原理

        首先,在Android系统中,每一次手势交互都会依照以下顺序执行。

       1. 接触接触屏一刹那,触发一个MotionEvent事件。

       2. 该事件被OnTouchListener监听,在其onTouch()方法里获得该MotionEvent对象。

       3. 通过GestureDetector转发MotionEvent对象至OnGestureListener。

       4. OnGestureListener获得该对象,根据该对象封装的的信息,响应对应的接口函数。


      而GestureDetector提供了两个侦听器接口,OnGestureListener处理单击类消息,而OnDoubleTapListener处理双击类消息。


      OnGestureListener的接口有这几个:

      

      abstract boolean onDown(MotionEvent e);   //单击,触摸屏按下时立刻触发      abstract boolean onSingleTapUp(MotionEvent e);   //抬起,手指离开触摸屏时触发(长按、滚动、滑动时,不会触发这个手势)      abstract void onShowPress(MotionEvent e);   //短按,触摸屏按下后片刻后抬起,会触发这个手势,如果迅速抬起则不会      abstract void onLongPress(MotionEvent e);   //长按,触摸屏按下后既不抬起也不移动,保持着按下,过一段时间后触发      abstract boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);  //滚动,触摸屏按下后移动,抬起时触发      abstract boolean onFling(MotionEvente1, MotionEvent e2, float velocityX, float velocityY);  //滑动,触摸屏按下后快速移动并抬起,会先触发滚动手势,跟着触发一个滑动手势

      OnDoubleTapListener的接口有这几个:

abstract boolean onDoubleTap(MotionEvent e);   //双击,手指在触摸屏上迅速点击两次,第二下的按下触发abstract boolean onDoubleTapEvent(MotionEvent e);   //双击,第二下的按下和抬起各触发一次abstract boolean onSingleTapConfirmed(MotionEvent e);  //单击确认,即很快的按下并抬起,但并不连续点击第二下

      有时候我们并不需要处理上面所有手势,而方便起见,Android提供了另外一个类SimpleOnGestureListener实现了如上接口,我们只需要继承SimpleOnGestureListener然后重载感兴趣的手势即可,这个可以通过内部类来实现。

      在这里需要特别说明一点,如果你想程序能够正确识别单击和双击,那你需要重写的函数是onSingleTapConfirmed和onDoubleTap,而不是onSingleTapUp和onDoubleTap。因为在响应onDoubleTap之前,是一定会响应onSingleTapUp的,这样会造成单双击混淆的结果。还需要提醒的是,程序响应onSingleTapConfirmed会有一定的延时,因为程序需要确认是单击而不是双击,这在一定程序上会影响用户体验,需要权衡。


      另外,onDown只要按下一定是立刻触发;而按下后过一会没有滑动先触发onShowPress再是onLongPress;如果按下后一直不滑动,触发顺序是onDown->onShowPress->onLongPress。如果点击一下非常快的(不滑动)然后抬起:onDown->onSingleTapUp->onSingleTapConfirmed。

      点击一下稍微慢点的(不滑动)然后抬起:onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed。

      进一步总结的还有:

      任何手势动作都会先执行一次按下(onDown)动作。

      长按(onLongPress)动作前一定会执行一次按住(onShowPress)动作。

      按住(onShowPress)动作和按下(onDown)动作之后都会执行一次抬起(onSingleTapUp)动作。

      长按(onLongPress)、滚动(onScroll)和滑动(onFling)动作之后都不会执行抬起(onSingleTapUp)动作。

原创粉丝点击