Android事件处理机制

来源:互联网 发布:lol美服安装包 mac 编辑:程序博客网 时间:2024/05/16 15:51

一.dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent区别

  • dispatchTouchEvent是第一个收到事件的接口,  无论在View还是ViewGroup中
  • onInterceptTouchEvent拦截接口在ViewGroup中才有因为拦截只是为了不向子View分发事件,View中并没有子View;
  • onTouchEvent接口是事件最终处理的地方;
          onTouchEvent返回Ture ,代表事件被处理,以后的move,up事件都会分发到该View继续处理;
          onTouchEvent返回False,则以后的move,up事件就不会分发到该View;

二.onInterceptTouchEvent详解

实现该方法用以拦截所有的屏幕触摸运动事件。它可以观察到所有分发到子视图的事件,并且在任何时候都拥有当前手势的所有权。该方法返回true表示拦截ViewGroup到子View的事件,false则相反。
简单说来onInterceptTouchEvent处理事件(类似于预处理,当然也可以不处理)并改变事件的传递方向,也就是决定是否允许Touch事件继续向下(子控件)传递,一但返回True(代表事件在当前的viewGroup中会被处理),则向下传递之路被截断(所有子控件将没有机会参与Touch事件),同时把事件传递给当前的控件的onTouchEvent()处理;返回false,则把事件交给子控件的onInterceptTouchEvent()。
使用该功能要十分的小心,因为他将会和View.onTouchEvent(MotionEvent)相当复杂的进行交互,并要求两个方法都要很好的实现。事件将以下列的顺序被接收:
  1. 该方法内将接收到DOWN事件。
  2. DOWN事件要不被子视图处理要不被ViewGroup自己的onTouchEvent()方法处理。处理的意思就是onToucheEvent()返回true,你就会继续接收到其他的手势(而不是寻找父视图来处理它)。如果ViewGroup的onToucheEvent()返回true,在onInterceptTouchEvent()中将不会接收到接下来的事件,所有的触摸处理像正常的发生在ViewGroup的onTouchEvent()中。
  3. 对于返回false的情况,接下来所有的事件(直到最终的UP事件)都会先被传递到这里然后才会传递给目标的onTouchEvent()(译者注:即返回true的onTouchEvent)。
  4. 如果该处返回true,这个方法内将不会接收到接下来所有的事件:目标的View会接收到CANCEL事件,并且接下来所有的事件都会分发到ViewGroup的onTouchEvent()方法,事件就不会出现在这里了。



ACTION_CANCEL事件:
当 当前控件(子控件,儿子)收到前驱事件(ACTION_MOVE或者ACTION_MOVE)后,它的父控件(老爸)突然插手,截断事件的传递,这时,当前控件就会收到ACTION_CANCEL,收到此事件后,不管子控件此时返回true或者false,都认为这一个动作已完成,不会再回传到父控件的OnTouchEvent中处理,同时后续事件,会通过dispatchEvent方法直接传送到父控件这里来处理。这和之前的结论有点相悖,之前说过如果子控件的OnTouchEvent返回false,表明事件未被处理,是回传到父控件去处理的,这里纠正一下,只有ACTION_DOWN事件才可以被回传,ACTION_MOVE和ACTION_UP事件会跟随ACTION_DOWN事件,即ACTION_DOWN是哪个控件处理的,后续事件都传递到这里,不会上抛到父控件,ACTION_CANCEL也不能回传。还有一点,触摸区域的范围问题,如果触摸区域在子控件内,同时父控件没有截断事件传递,刚不管子控件是否拦截此事件,都会传递到子控件的OnTouchEvent中处理,可以看成一种责任吧,因为我点的就是你,你父亲没有拦截,说明他不想处理,那到你这里了,不管你拦不拦截,都得你来处理。

结论:ACTION_CANCEL事件是收到前驱事件后,后续事件被父控件拦截的情况下产生,onTouchEvent的事件回传到父控件只会发生在ACTION_DOWN事件中



0 0
原创粉丝点击