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

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:

事件Activityfatherchild
dispatchTouchEventsuper.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)
onInterceptTouchEvent….super.onInterceptTouchEvent(ev)super.onInterceptTouchEvent(ev)
onTouchEventsuper.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:

事件Activityfatherchild
dispatchTouchEventtruesuper.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)
onInterceptTouchEvent….super.onInterceptTouchEvent(ev)super.onInterceptTouchEvent(ev)
onTouchEventsuper.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:

事件Activityfatherchild
dispatchTouchEventsuper.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)
onInterceptTouchEvent….truesuper.onInterceptTouchEvent(ev)
onTouchEventsuper.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:

事件Activityfatherchild
dispatchTouchEventsuper.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)
onInterceptTouchEvent….super.onInterceptTouchEvent(ev)super.onInterceptTouchEvent(ev)
onTouchEventsuper.onTouchEvent(event)truesuper.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:

事件Activityfatherchild
dispatchTouchEventsuper.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)
onInterceptTouchEvent….truesuper.onInterceptTouchEvent(ev)
onTouchEventsuper.onTouchEvent(event)truesuper.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:

事件Activityfatherchild
dispatchTouchEventsuper.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)super.dispatchTouchEvent(ev)
onInterceptTouchEvent….super.onInterceptTouchEvent(ev)
super.onInterceptTouchEvent(ev)
onTouchEventsuper.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值