View里提供的回调在我描述的场景里,并不能满足要求。因此,GestureDetector出场了。我需要对其啃透才能写出自己的ActionDetector。
GestureDetector类可以帮助我们分析用户的动作,和View的onTouchEvent的处理方式差不多,但分析的动作类型更加细致,以下是它的回调接口:
Java代码:
- public interface OnGestureListener {
- // Touch down时触发, e为down时的MotionEvent
- boolean onDown(MotionEvent e);
- // 在Touch down之后一定时间(115ms)触发,e为down时的MotionEvent
- void onShowPress(MotionEvent e);
- // Touch up时触发,e为up时的MotionEvent
- boolean onSingleTapUp(MotionEvent e);
- // 滑动时触发,e1为down时的MotionEvent,e2为move时的MotionEvent
- boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
- // 在Touch down之后一定时间(500ms)触发,e为down时的MotionEvent
- void onLongPress(MotionEvent e);
- // 滑动一段距离,up时触发,e1为down时的MotionEvent,e2为up时的MotionEvent
- boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
- }
- public interface OnDoubleTapListener {
- // 完成一次单击,并确定没有二击事件后触发(300ms),e为down时的MotionEvent
- boolean onSingleTapConfirmed(MotionEvent e);
- // 第二次单击down时触发,e为第一次down时的MotionEvent
- boolean onDoubleTap(MotionEvent e);
- // 第二次单击down,move和up时都触发,e为不同时机下的MotionEvent
- boolean onDoubleTapEvent(MotionEvent e);
- }
有了这么多的回调消息,我们就能更加方便的对用户的动作进行响应,那么,这个类如何使用呢?以下是使用该类的一个范例:
java代码:
- private GestureDetector mGestureDetector;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mGestureDetector = new GestureDetector(this, new MyGestureListener());
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- return mGestureDetector.onTouchEvent(event);
- }
- class MyGestureListener extends GestureDetector.SimpleOnGestureListener{
- @Override
- public boolean onSingleTapUp(MotionEvent ev) {
- Log.d("onSingleTapUp",ev.toString());
- return true;
- }
- @Override
- public void onShowPress(MotionEvent ev) {
- Log.d("onShowPress",ev.toString());
- }
- @Override
- public void onLongPress(MotionEvent ev) {
- Log.d("onLongPress",ev.toString());
- }
- }
基本的内容就是创建一个GestureDetector的对象,传入listener对象,在自己接收到的onTouchEvent中将event传给GestureDetector进行分析,listener会回调给我们相应的动作。其中GestureDetector.SimpleOnGestureListener(Framework帮我们简化了)是实现了上面提到的OnGestureListener和OnDoubleTapListener两个接口的类,我们只需要继承它并重写其中我们关心的回调即可。
最后,再提一下双击和三击的识别过程:在第一次单击down时,给Hanlder发送了一个延时300ms的消息,如果300ms里,发生了第二次单击的down事件,那么,就认为是双击事件了,并移除之前发送的延时消息。
转:http://dev.10086.cn/cmdn/wiki/index.php?doc-view-6978.html
另外的一篇关于这些这些方法调用时机的说明(最主要的是后面几个方法的说明可能比上面更直接):
为了加强鼠标响应事件,Android提供了GestureDetector手势识别类。通过GestureDetector.OnGestureListener来获取当前被触发的操作手势(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling),具体包括以下几种:
boolean onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发
boolean onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
boolean onDown(MotionEvent e)
解释:Touch down时触发
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解释:Touch了滑动一点距离后,up时触发。
void onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解释:Touch了滑动时触发。
void onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较
onDown只要Touch down一定立刻触发。
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。
boolean onSingleTapConfirmed(MotionEvent e)
boolean onSingleTapUp(MotionEvent e)
解释:上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。
点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
转:http://blog.youkuaiyun.com/aben_2005/article/details/6417423
1.点击屏幕上的某项的执行流程
时间很短:onDown--------》onSingleTapUp--------》onSingleTapConfirmed
时间稍长:onDown--------》onShowPress------》onSingleTapUp--------》onSingleTapConfirmed
2. 长按事件
onDown--------》onShowPress------》onLongPress
3.抛:手指触动屏幕后,稍微滑动后立即松开
onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
4.拖动
onDown------》onScroll----》onScroll------》onFiling
注意:有的时候会触发onFiling,但是有的时候不会触发,个人理解是人的动作不标准所致。