Android 事件分发机制测试以及总结

来源:互联网 发布:jquery创建json数组 编辑:程序博客网 时间:2024/05/21 06:26

Android 事件分发机制测试以及总结

代码借鉴:http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html

(补充文档:http://blog.csdn.net/xyz_lmn/article/details/12517911,总结比较充分,从activity,view,view group,个人觉得对事件有了一定了解再看这篇后会明朗很多)

记得之前看了很多的事件分发机制类的文章,当时是理解了,慢慢时间长了没有编写相关代码就又给忘了,这边借鉴楼上的代码然后自己测试记录一下事件分发的整个过程。

一、dispatchTouchEvent

首先从dispatchTouchEvent开始:

CASE 1:

事件 Activity father child dispatchTouchEvent super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) onInterceptTouchEvent …. super.onInterceptTouchEvent(ev) super.onInterceptTouchEvent(ev) onTouchEvent super.onTouchEvent(event) super.onTouchEvent(ev) super.onTouchEvent(ev)

运行结果

 TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN TouchEventChilds | dispatchTouchEvent --> ACTION_DOWN TouchEventChilds | onInterceptTouchEvent --> ACTION_DOWN TouchEventChilds | onTouchEvent --> ACTION_DOWN TouchEventFather | onTouchEvent --> ACTION_DOWN TouchEventActivity | onTouchEvent --> ACTION_DOWN TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventActivity | onTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_UP TouchEventActivity | onTouchEvent --> ACTION_UP

分析

事件首先从activity中传递下去,怎么传递的,首先是phonewindow中传递decorview中,然后按照正常的事件分发到fatherlayout这里.然后f再到child这里,我们看到dispatchTouchEvent是从上到下,从大到小这样传递的。

总结

事件的dispatchTouchEvent分发是从父到子的这样一个分发过程。

CASE 2:

事件 Activity father child dispatchTouchEvent true super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) onInterceptTouchEvent …. super.onInterceptTouchEvent(ev) super.onInterceptTouchEvent(ev) onTouchEvent super.onTouchEvent(event) super.onTouchEvent(ev) super.onTouchEvent(ev)

运行结果

 TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_UP

分析

这里很明显的啊,没有调用super.dispatchTouchEvent(ev) ,而是直接在activity中返回true,那么子view是收不到分发的事件的。

总结

到这里的话我们基本认识了dispatchTouchEvent这个方法了,它是从父view传递到子view的,负责事件的分发,不管是return true或者false它都不会继续分发下去

二、onInterceptTouchEvent

根据各种资料了解到它是一个拦截事件的方法,下面对它怎么拦截进行分析,我们选fatherlayout进行试验

CASE:

事件 Activity father child dispatchTouchEvent super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) onInterceptTouchEvent …. true super.onInterceptTouchEvent(ev) onTouchEvent super.onTouchEvent(event) super.onTouchEvent(ev) super.onTouchEvent(ev)

运行结果

 TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN TouchEventFather | onTouchEvent --> ACTION_DOWN TouchEventActivity | onTouchEvent --> ACTION_DOWN TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventActivity | onTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_UP TouchEventActivity | onTouchEvent --> ACTION_UP

分析

可以看到事件在TouchEventFather这边就停止向子view分发了,它经过ontouchevent之后就回传了。当设置为false或者super.onInterceptTouchEvent(ev)(其实返回值为false)的时候可以看到child中dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent都有输出,这里就不列出来了。

总结

onInterceptTouchEvent为true的时候,拦截当前事件,阻止向子view发送。

二、onTouchEvent

这里因为是最后一条,综合考虑上面的两个方法的情况来进行分析,先上几个case:

CASE1:

事件 Activity father child dispatchTouchEvent super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) onInterceptTouchEvent …. super.onInterceptTouchEvent(ev) super.onInterceptTouchEvent(ev) onTouchEvent super.onTouchEvent(event) true super.onTouchEvent(ev)

运行结果

 TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN TouchEventChilds | dispatchTouchEvent --> ACTION_DOWN TouchEventChilds | onInterceptTouchEvent --> ACTION_DOWN TouchEventChilds | onTouchEvent --> ACTION_DOWN TouchEventFather | onTouchEvent --> ACTION_DOWN TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | onTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | onTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_UP TouchEventFather | dispatchTouchEvent --> ACTION_UP TouchEventFather | onTouchEvent --> ACTION_UP  ##说明: child中的事件完整分发过后,事件都由father的ontouchevent消费了

CASE2:

事件 Activity father child dispatchTouchEvent super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) onInterceptTouchEvent …. true super.onInterceptTouchEvent(ev) onTouchEvent super.onTouchEvent(event) true super.onTouchEvent(ev)

运行结果

 TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN TouchEventFather | onTouchEvent --> ACTION_DOWN TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | onTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | onTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_UP TouchEventFather | dispatchTouchEvent --> ACTION_UP TouchEventFather | onTouchEvent --> ACTION_UP  ##说明: child中的事件已经被father拦截了,而且事件都由father的ontouchevent消费了

CASE3:

事件 Activity father child dispatchTouchEvent super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) super.dispatchTouchEvent(ev) onInterceptTouchEvent …. super.onInterceptTouchEvent(ev) super.onInterceptTouchEvent(ev) onTouchEvent super.onTouchEvent(event) super.onTouchEvent(ev) true

运行结果

 TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | dispatchTouchEvent --> ACTION_DOWN TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN TouchEventChilds | dispatchTouchEvent --> ACTION_DOWN TouchEventChilds | onInterceptTouchEvent --> ACTION_DOWN TouchEventChilds | onTouchEvent --> ACTION_DOWN TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | dispatchTouchEvent --> ACTION_MOVE TouchEventFather | onInterceptTouchEvent --> ACTION_MOVE TouchEventChilds | dispatchTouchEvent --> ACTION_MOVE TouchEventChilds | onTouchEvent --> ACTION_MOVE TouchEventActivity | dispatchTouchEvent --> ACTION_UP TouchEventFather | dispatchTouchEvent --> ACTION_UP TouchEventFather | onInterceptTouchEvent --> ACTION_UP TouchEventChilds | dispatchTouchEvent --> ACTION_UP TouchEventChilds | onTouchEvent --> ACTION_UP      ##说明: father中的ontouchevent没能消费事件,事件由child的ontouchevent消费了

总结

ontouchevent分发是由子向父的,由下向上的分发。返回true,则不继续向父view分发。

整体总结一下:

  • dispatchTouchEvent负责事件分发,分发方向是由上向下,有父及子的分发(当返回super.dispatchTouchEvent(ev)的时候);当返回true的时候,直接由该方法消费,TouchEventFather | dispatchTouchEvent –> ACTION_UP,当返回false的时候,则不再分发,有父view消费TouchEventActivity | onTouchEvent –> ACTION_UP
  • onInterceptTouchEvent负责事件拦截,拦截完后由onTouchEvent处理,返回true表示拦截,不继续分发,false表示继续分发
  • onTouchEvent分发由下向上,由子及父的分发,从下向上看,当返回true的时候由最小得孩子处理该事件,不再继续向父view分发(当然可以看到如果父view进行了拦截处理时事件压根不会传递到子view——-当然被拦截了子view理所当然无法消费)
0 0
原创粉丝点击