美文网首页
对Android事件分发机制的一次探究

对Android事件分发机制的一次探究

作者: 一敬 | 来源:发表于2019-04-19 14:33 被阅读0次

            在网上关于事件分发机制的文章有很多,有些观点认为事件是最先被外层的View捕获到然后在分发有些观点认为事件的分发是从Activity开始的。既然有不同的观点,只好自己做一些实验,来验证。主要是想看一下Android事件分发(dispatchTouchEvent),拦截(onInterceptTouchEvent),处理(onTouchEvent)的顺序。下面是我的一些探究,现发布出来供大家一起学习探讨。

           我们首先定义这样一个视图层次,三个自定义ViewGroup ,一个自定义View。重写了自定义ViewGroup的dispatchTouchEvent,onInterceptTouchEvent 和 onTouchEvent方法,重写了自定义View的dispatchTouchEvent和onTouchEvent方法,通过打印log的方式查看事件流的顺序。

    layer

    我对以下几种情况的事件流的分发做了一些实验:

    1. 在三层自定义ViewGruop不做任何拦截处理:在一次点击事件之后,查看事件流

    event flow

    我们可以看到事件流是这样的: FirstLayer -->SecondLayer-->ThirdLayer-->FourthButton,在ViewGroup中会先调用dispatchTouchEvent然后调用onInterceptTouchEvent。

    onInterceptTouchEvent是ViewGroup才有的方法,我们通过查看ViewGroup发现onInterceptTouchEvent是在dispatchTouchEvent中被调用,所有onInterceptTouchEvent都是在dispatchTouchEvent后出现。onTouchEvent也是在dispatchTouchEvent中调用。

    2.如果我们重写dispatchTouchEvent,并且不去调用父类中的dispathTouchEvent方法时,事件拦截(onInterptTouchEvent)和事件处理(onTouchEvent)会失效。重写FirstLayer中的dispathTouchEvent方法,SecondLayer和ThridLayer中的方法就不会被调用。重写ThirdLayer的dispatchTouchEvent方法后,对FirstLayer和SecondLayer没有影响,这也说明了事件分发的方向。

    3.重写onInterptTouchEvent

    onInterptTouchEvent只存在与ViewGroup中,一个ViewGroup想要处理一个事件时需要先重写onInterptTouchEvent方法让他返回ture。在SecondLayer中我想要对move事件作拦截后,在拦截后move事件最终会转变成up或cancel事件,之后up和cancel事件都会直接交给这个SecondLayer的onTouchEvent处理,而不用在调用onInterptTouchEvent。

    4.重写onTouchEvent

    onTouchEvent中一般是对事件处理的具体逻辑,在onInterptTouchEvent中拦截后在onTouchEvent中去处理,如果他返回true,就表示这次事件处理完成,如果返回false这次事件会返回给上一层处理。

    如果我在ThirdLayer中在onInterptTouchEvent中返回true拦截事件,在onTouchEvent中返回false就表示ThirdLayer不会处理这次事件,这次事件会返回给SecondLayer处理。之后的事件也会给SecondLayer处理,不会再分发给ThirdLayer。

    总结:

    一次Down事件分发顺序:FirstLayer-->SecondLayer-->ThirdLayer-->FourthButton,如果FourthButton消费Down事件,并且前面ViewGroup不再进行拦截,后面的Up或Cancle事件都会直接交给FourthButton来处理。

    FourthButton中不处理事件:在FouthButton中onTouchEvent中返回false,表示事件没有处理,事件会返回给ThirdLayer去做处理,如果ThirdLayer也不做处理就会继续返回。

    在ThirdLayer中拦截事件但不处理:在ThirdLayer中onInterptTouchEvent中返回true,会调用onTouchEvent,在onTouchEvent中返回false,事件会返回到SecondLayer处理,以后事件也是直接交给SecondLayer处理。

    ps:第一次想要写好一篇技术文章,写文章不容易。。。

    相关文章

      网友评论

          本文标题:对Android事件分发机制的一次探究

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