这里有完整代码,源码下载
图解因为看不见画图的先后顺序,不容易体会思路,我就不上图了。
先指出事件分发的三个方法
dispatch 英文释义 派遣,调度,我们可以理解为分发。
事件一:dispatchTouchEvent 分发
Intercept 英文释义 截距; 截击,拦截; 截听; 拦截者;中断
事件二:onInterceptTouchEvent 拦截
事件三:onTouchEvent 处理
它们的返回值都是boolean.我们先不说理论,直接写代码做实验,用实验结果说话。
如上图所示,布局大概就是activity中最外层viewgroupA,它包裹viewgroupB, b里面有个view.
Override上述三个方法,里面啥都不干,只打印日志。(ps:activity和view是没有onInterceptTouchEvent方法的,很好理解,activity拦截事件给谁消费呢?view是责任链的最后一层,自然也不用拦截事件)
实验一:
1.复写各自上述三个方法,里面啥都不干。因为涉及到多个事件,所以我们只在down事件发生时,打印日志。
2.点击view,查看日志打印
如上图,事件分发大概就是一个责任链的模式。
第一阶段:先走activity的向下“分发”,到viewgroup的“分发”,再到viewgroup特有的方法“是否拦截”,以此类推,再走下层viewgroup的“分发”,再走下层viewgroup的“是否拦截”,再到view的“分发”
第二阶段:走view的“处理”,再走viewgroupB的“处理”,再走viewGroupA的“处理”,再走activity的“处理”
问题:那么问题来了,假设在第一阶段中的,“分发”方法dispatchTouchEvent中返回true,该当如何?
实验二:
1.将viewGroupB的“分发”事件返回true.其他不变
2.点击view,查看日志
由上可看,事件在第一阶段即中止,中止于viewGroupB的“分发”阶段
问题:假设在第一阶段中的,“是否拦截”方法onInterceptTouchEvent中返回true,该当如何?
实验三:
1.将viewGroupB的“是否拦截”事件返回true.其他不变
2.点击view,查看日志
由上图可看,事件没有被中断,同样也是一个责任链,只不过没有走到view那一层。
第一阶段:先走activity的向下“分发”,到viewgroup的“分发”,再到viewgroup特有的方法“是否拦截”,以此类推,再走下层viewgroup的“分发”,再走下层viewgroup的“是否拦截”,拦截了,就自己处理
第二阶段:走viewgroupB自己的“处理”,再走viewGroupA的“处理”,再走activity的“处理”
问题:如果在“处理”方法中返回true,又该当如何呢?
实验四:
1.将viewGroupB的“处理”事件返回true.其他不变
2.点击view,查看日志
看图,责任链的第一阶段,是完全没有变化的。第二阶段,止步于自己的“处理”方法
第一阶段:先走activity的向下“分发”,到viewgroup的“分发”,再到viewgroup特有的方法“是否拦截”,以此类推,再走下层viewgroup的“分发”,再走下层viewgroup的“是否拦截”,再到view的“分发”
第二阶段:走view的“处理”,再走viewgroupB自己的的“处理”,事件中止。
这里有完整代码,源码下载