手势识别 GestureDetector ScaleGestureDetector

Posted 白乾涛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手势识别 GestureDetector ScaleGestureDetector相关的知识,希望对你有一定的参考价值。

2017-3-6

单点触摸手势识别器GestureDetector

当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等。一般情况下,我们可以通过View或Activity的onTouchEvent,或实现OnTouchListener接口后通过onTouch方法,处理一些touch事件,但是这个方法太过简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦(因为我们要自己根据用户触摸的轨迹去判断是什么手势)。为此,android 给我们提供了GestureDetector(Gesture:手势,Detector:识别),通过这个类我们可以识别很多的手势。虽然他能识别手势,但是不同的手势要怎么处理,还是给程序员自己要实现的。

注意:
默认情况下,GestureDetector是监听不到MotionEvent事件的,也即GestureDetector的onTouchEvent方法是不会被调用的,若要被调用,可用下面三种方式之一:
  • 如果View【没有】设置OnTouchListener,可以在View的onTouchEvent()方法中将MotionEvent事件传给GestureDetector
  • 如果View设置了OnTouchListener,可onTouch()方法中将MotionEvent事件传给GestureDetector
  • 如果View设置了OnTouchListener,并且onTouch()的返回值是false,那么也可以在onTouchEvent()方法中将MotionEvent事件传给GestureDetector;如果onTouch()的返回值是true,那么只能onTouch()方法中将MotionEvent事件传给GestureDetector
只有这样,GestureDetector注册的OnGestureListener(单击)或OnDoubleTapListener(双击)才能获得完整的MotionEvent事件,进而根据该对象封装的的信息,做出合适的反馈。


GestureDetector:
Detects发现 various gestures and events using the supplied {@link MotionEvent}s. The {@link OnGestureListener} callback will notify users when a particular特殊的 motion event has occurred. This class should only be used with {@link MotionEvent}s reported via touch (don\'t use for trackball events).  To use this class:
  • Create an instance of the {@code GestureDetector} for your {@link View} 
  • In the {@link View#onTouchEvent(MotionEvent)} method ensure you call {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback will be executed when the events occur. 
  • If listening for {@link OnContextClickListener#onContextClick(MotionEvent)}  you must call {@link onGenericMotionEvent(MotionEvent)} in {@link View#onGenericMotionEvent(MotionEvent)}. 

onTouchEvent:
Analyzes分析 the given motion运动 event and if applicable适合 triggers触发 the appropriate适当的 callbacks on the OnGestureListener supplied提供的.return true if the OnGestureListener consumed销毁 the event, else false.

GestureDetector的回调方法

们只需要继承SimpleOnGestureListener重载自己需要监听的手势即可。
中,OnGestureListener的监听事件有:
  • 按下 onDown: 刚刚手指接触到触摸屏的那一刹那,就是触的那一下
  • 抛掷 onFling: 手指在触摸屏上迅速移动,并松开的动作,onDown---onScroll---onScroll---…onFling
  • 长按 onLongPress: 手指按在持续一段时间,并且没有松开
  • 滚动 onScroll: 手指在触摸屏上滑动,onDown---onScroll---onScroll---…onScroll
  • 按住 onShowPress: 手指按在触摸屏上,在按下起效,在长按前失效,onDown->onShowPress->onLongPress
  • 抬起 onSingleTapUp:手指离开触摸屏的那一刹那
OnDoubleTapListener的监听事件有:
  • onDoubleTap,双击的【第二下】down时触发(只执行一次)
  • onDoubleTapEvent,双击的【第二下】down和up都会触发(执行次数不确定)
  • onSingleTapConfirmed,单击确认,即很快的按下并抬起,但并不连续点击第二下

注意:
  • onSingleTapConfirmed和onSingleTapUp都是在down后既没有滑动(onScroll),又没有长按(onLongPress)时, up时触发的
  • 非常快的点击一下:onDown->onSingleTapUp->onSingleTapConfirmed
  • 稍微慢点的点击一下:onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed(最后一个不一定会触发)


OnGestureListener:
The listener that is used to notify when gestures occur. If you want to listen for all the different gestures then implement this interface. If you only want to listen for a subset it might be easier to extend {@link SimpleOnGestureListener}.

OnDoubleTapListener:
The listener that is used to notify when a double-tap or a confirmed single-tap occur.

SimpleOnGestureListener:
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener, OnContextClickListener
A convenience方便的 class to extend when you only want to listen for a subset子集 of all the gestures. * This implements all methods in the OnGestureListener, OnDoubleTapListener, and OnContextClickListener * but does nothing and return {@code false} for all applicable methods.


OnGestureListener接口简介
public interface OnGestureListener {
/**
* Notified when a tap occurs with the down {@link MotionEvent} that triggered it. 
* This will be triggered immediately for every down event. All other events should be preceded先于 by this.
* @param e The down motion event.
*/
boolean onDown(MotionEvent e);

/**
* The user has performed执行 a down {@link MotionEvent} and not performed a move or up yet. 
* This event is commonly通常 used to provide visual视觉 feedback反馈 to the user to let them know
* that their action has been recognized验证 i.e. 换言之highlight an element.
* @param e The down motion event
*/
void onShowPress(MotionEvent e);

/**
* Notified when a tap occurs with the up {@link MotionEvent} that triggered it.
* @param e The up motion event that completed the first tap
* @return true if the event is consumed, else false
*/
boolean onSingleTapUp(MotionEvent e);

/**
* Notified when a scroll occurs with the initial on down {@link MotionEvent} and the
* current move {@link MotionEvent}. The distance in x and y is also supplied for convenience遍历.
*
* @param e1 The first down motion event that started the scrolling. 注意e1是不变的
* @param e2 The move motion event that triggered the current当前的 onScroll. 而e2是时刻变的
* @param distanceX The distance along the X axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1} and {@code e2}.
* @param distanceY The distance along the Y axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1} and {@code e2}.
* @return true if the event is consumed, else false
*/
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);

/**
* Notified when a long press occurs with the initial on down {@link MotionEvent} that trigged it.
* @param e The initial on down motion event that started the longpress.
*/
void onLongPress(MotionEvent e);

/**
* Notified of a fling投掷 event when it occurs with the initial on down {@link MotionEvent}
* and the matching up {@link MotionEvent}. The calculated velocity计算出的速度 is supplied along
* the x and y axis in pixels per second. 像素/秒
* @param e1 The first down motion event that started the fling.
* @param e2 The move motion event that triggered the current onFling.
* @param velocityX The velocity of this fling measured in pixels per second along the x axis.
* @param velocityY The velocity of this fling measured in pixels per second along the y axis.
* @return true if the event is consumed, else false
*/
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
}
2017-3-6

缩放手势识别器ScaleGestureDetector

ScaleGestureDetector是Android2.2中增加的类,用于处理缩放手势的工具类,用法与GestureDetector类似,都是通过onTouchEvent()关联相应的MotionEvent。ScaleGestureDetector能使 Views 通过接收到的MotionEvent检测包括多点触摸在内的手势变化信息,当检测到此类信息后,监听器OnScaleGestureListener便会调用相应的回调方法通知用户

ScaleGestureDetector中定义的公共方法: