美文网首页应用层的知识归纳看看
Android 事件分发机制详解

Android 事件分发机制详解

作者: KT_11 | 来源:发表于2018-10-25 22:58 被阅读62次
    目录

    1 完整流程图

    下图就是完整的事件分发流程

    • 建议点开、查看原图放大观看
    • 心里反复多走几遍流程,三种主要方法 true 或 false 分别会走向哪里
    • 此图可以说是本文的精髓所在,掌握了此图,也就相当于掌握了事件分发

    2 具体分析

    由于上面这张图太大,下面暂时用一张简化版的图代替,以便于我们分析
    OK,我们开始!

    • 首先可以看到,从上至下分为三层,依次是Activity、ViewGroup、View
      事件分发的顺序基本上就是这样,假设有中间多层ViewGroup
      顺序仍然是由 Activity -> ViewGroup ->ViewGroup ->.......->View
      从上至下最终到达最末端的View
    • 接着我们需要清楚最主要的三个方法:
      dispatchTouchEvent():分发
      onInterceptTouchEvent():拦截
      onTouchEvent():处理(对点击触摸事件进行处理)

      而且,其中仅仅只有 ViewGroup 拥有 onInterceptTouchEvent 拦截的方法
    • 这三个方法均都有返回值,return true、return false、return super.xxxxx(),super 的意思是调用父类实现
    • dispatchTouchEvent和 onTouchEvent的框里有个【true---->消费】的字,表示的意思是如果方法返回true,那么代表事件就此消费,不会继续往别的地方传了,事件终止
    • 目前所有的图的事件是针对ACTION_DOWN的,对于ACTION_MOVE和ACTION_UP我们最后做分析

    2-1 要点

    请记住以下的结论,当然我们会过一遍,然后帮助我们在理解中记忆

    1 如果事件不被中断,整个事件流向是一个类U型图

    • 仔细看上图
    • 所以如果我们没有对控件里面的方法进行重写或更改返回值,而直接用super调用父类的默认实现,那么整个事件流向应该是从Activity---->ViewGroup--->View 从上往下调用dispatchTouchEvent方法,一直到末端View的时候,再由View--->ViewGroup--->Activity从下往上调用onTouchEvent方法。

    2 dispatchTouchEvent 和 onTouchEvent 一旦return true,事件就停止传递了,我们可以理解为事件被消费了,消费了的意思就是事件走到这里就是终点,不会往下传,没有谁能再收到这个事件了

    3 dispatchTouchEvent 和 onTouchEvent 都return false的时候事件都回传给父控件的onTouchEvent处理

    • 可以简单理解为:任务从上级派发下来,我搞不定,只能反过来丢给我上级处理

    4 dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
    ViewGroup 和View的这些方法的默认实现就是会让整个事件安装U型完整走完,所以 return super.xxxxxx() 就会让事件依照U型的方向的完整走完整个事件流动路径),中间不做任何改动,不回溯、不终止,每个环节都走到

    5 onInterceptTouchEvent的作用

    • Intercept 的意思就拦截,每个ViewGroup每次在做分发的时候,问一问拦截器要不要拦截(也就是问问自己这个事件要不要自己来处理)
      如果要自己处理那就在onInterceptTouchEvent方法中 return true就会交给自己的onTouchEvent的处理
      如果不拦截就是继续往子控件往下传。默认是不会去拦截的,因为子View也需要这个事件,所以onInterceptTouchEvent拦截器return super.onInterceptTouchEvent()和return false是一样的,是不会拦截的,事件会继续往子View的dispatchTouchEvent传递

    2-2 总结

    最后总结一下:

    • 对于 dispatchTouchEvent,onTouchEvent,return true是终结事件传递。return false 是回溯到父View的onTouchEvent方法。
    • ViewGroup 想把自己分发给自己的onTouchEvent,需要拦截器onInterceptTouchEvent方法return true 把事件拦截下来。
    • ViewGroup 的拦截器onInterceptTouchEvent 默认是不拦截的,所以return super.onInterceptTouchEvent()=return false;
    • View 没有拦截器,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent。

    2-3 关于ACTION_MOVE 和 ACTION_UP

    1、我们在ViewGroup1 的dispatchTouchEvent 方法返回true消费这次事件

    • 在这种场景下ACTION_MOVE和ACTION_UP会执行到哪一步
      我们看下面的打出来的日志
    Activity | dispatchTouchEvent --> ACTION_MOVE 
    ViewGroup1 | dispatchTouchEvent --> ACTION_MOVE
    ----
    TouchEventActivity | dispatchTouchEvent --> ACTION_UP 
    ViewGroup1 | dispatchTouchEvent --> ACTION_UP
    ----
    

    下图中
    红色的箭头代表ACTION_DOWN 事件的流向
    蓝色的箭头代表ACTION_MOVE 和 ACTION_UP 事件的流向


    2、接着我们在ViewGroup2 的dispatchTouchEvent 返回true消费这次事件
    红色的箭头代表ACTION_DOWN 事件的流向
    蓝色的箭头代表ACTION_MOVE 和 ACTION_UP 事件的流向


    3、我们在View 的dispatchTouchEvent 返回true消费这次事件
    这里就不赘述了,和第二个例子几乎一模一样

    我们可以得出结论如果在某个控件的dispatchTouchEvent 返回true消费终结事件,那么如果能收到ACTION_DOWN 的事件,那么也能收到 ACTION_MOVE和ACTION_UP事件

    再看另一种情况

    4、我们在View 的onTouchEvent 返回true消费这次事件
    红色的箭头代表ACTION_DOWN 事件的流向
    蓝色的箭头代表ACTION_MOVE 和 ACTION_UP 事件的流向

    5、我们在ViewGroup 2 的onTouchEvent 返回true消费这次事件
    红色的箭头代表ACTION_DOWN 事件的流向
    蓝色的箭头代表ACTION_MOVE 和 ACTION_UP 事件的流向

    6、我们在ViewGroup 1 的onTouchEvent 返回true消费这次事件
    红色的箭头代表ACTION_DOWN 事件的流向
    蓝色的箭头代表ACTION_MOVE 和 ACTION_UP 事件的流向

    我们可以发现,在哪个View的onTouchEvent 返回true,那么ACTION_MOVE和ACTION_UP的事件从上往下传到这个View后就不再往下传递了,而直接传给自己的onTouchEvent 并结束本次事件传递过程。

    还有其他几种也属于和上面类似的情况......

    最后我们得出结论:

    • ACTION_DOWN事件在哪个控件消费了(return true), 那么ACTION_MOVE和ACTION_UP就会从上往下(通过dispatchTouchEvent)做事件分发往下传,就只会传到这个控件,不会继续往下传
    • 如果ACTION_DOWN事件是在dispatchTouchEvent消费,那么事件到此为止停止传递
      如果ACTION_DOWN事件是在onTouchEvent消费的,那么会把ACTION_MOVE或ACTION_UP事件传给该控件的onTouchEvent处理并结束传递。

    参考致谢:

    https://www.jianshu.com/p/e99b5e8bd67b
    https://blog.csdn.net/ezview_uniview/article/details/77619900#commentBox

    相关文章

      网友评论

        本文标题:Android 事件分发机制详解

        本文链接:https://www.haomeiwen.com/subject/nrziaftx.html