View的Touch事件的分发系列-(1)ACTION_DOWN事件分发流程分析

在Android开发的知识体系中,其中View体系尤为重要,我们在平常的开发当中,无处不是View,很多人曾经都遇到过可滑动View嵌套的冲突问题,回想一下之前都是怎么处理的呢。还有一些在平常开发过程中需要去自定义开发的手势滑动交互的View,比如Android sdk提供了横向滑动的ViewPager,但是实际开发中,可能有垂直滑动的ViewPager的需求,如果我们自己开发,肯定离不开View的touch事件的处理。

上面说了那么多,其实就一句话“搞清楚View的Touch事件”非常重要。

我猜测,阅读我这篇博文的小伙伴,可能曾经也看过一些类似的文章,但如果没有以正确姿势阅读,估计不能形成对View的touch事件分发流程【自己的总结】,另外本篇文章遵循结构思维方法里面的结论现行的阐述方式,先阐述结论,做简单分析,后续再从源码的角度,验证结论。

建议阅读本系列文章的姿势:结合源码+编写Demo验证文中的我的总结。

目标:真正搞清楚View的Touch事件的分发流程。将本篇文章中正确的总结变成【你的总结】。

系列计划:View的Touch事件的分发系列

(1)ACTION_DWON事件分发流程分析
(2)ACTION_MOVE/ACTION_UP事件分发流程分析
(3)onTouch、onTouchEvent、onClick三者之间的关系
(4)View滑动事件冲突的分类和处理办法
(5)自定义组件开发实践系列

(1)ACTION_DOWN事件分发流程分析

先直接上一张总结性的事件分发的流程图:

说明:
①上图分为三层、依次是Activity、ViewGroup、View,整体图形看似是一个U型结构。
②上图仅仅针对ACTION_DOWN事件、MOVE和UP事件,会另行单独说明。

针对这张图一些结论:
1.Activity的dispatchTouchEvent 只有在return super.dispatchTouchEvent(ev)时,事件才会向下传递;如果重写dispatchTouchEvent方法直接返回true或者false,事件都被activity消费。

2.如果没有对Activity、ViewGroup、View组件中的三个核心方法进行重载和修改方法返回值即默认实现情况下,那么整个事件的分发流程会完整的完成上图U型路径。
整个事件的流向是Activity->ViewGroup->View从上往下调用dispatchTouchEvent方法,再由叶子节点的View->ViewGroup->Activity从下往上调用onTouchEvent。、

3.dispatchTouchEvent和onTouchEvent一旦return true,事件就被消费,当前的ACTION_DWON事件不会再传递给View树里面的其它View。

4.dispatchTouchEvent和onTouchEvent return false,事件都会回传给父控件的onTouchEvent去处理。事件分发递归流程终止,事件进行反向回溯,寻找真正的时间消费者。显然当前情况下onTouchEvent如果返回true,表示当前View消费了事件;返回false,表示当前View不消费事件,并且让事件继续向上回溯。

5.在ViewGroup中的onInterceptTouchEvent方法,用来在ViewGroup每次做事件分发的时候,确认自己是否要处理这个事件,如果自己要处理,就在此方法中return true,并交给自己的onTouchEvent处理;false,就继续向下传递。
默认情况下ViewGroup的onInterceptTouchEvent不会去拦截事件,即return false和return super.onInterceptTouchEvent的结果是一致的,事件会继续向子View的dispatchTouchEvent进行传递。因为每一个View都应该有接受事件的权利。

6.ViewGroup的onInterceptTouchEvent能够被调用,需要当前ViewGroup的dispatchTouchEvent实现return super.dispatchTouchEvent方法。

仔细阅读3、4、5会发现,有描述上看似有些冲突。dispatchTouchEvent方法,返回true,终止了事件的传递;返回false,交给了上一层view的onTouchEvent去处理;显然ViewGroup的dispatchTouchEvent无论是返回true和false,都没法让事件交给自己的onInterceptTouchEvent方法来确认是否要拦截。所以正如6的结论所述,要求dispatchTouchEvent实现return super.dispatchTouchEvent方法。这也是正式ViewGroup的默认实现。

上面阐述了ViewGroup的dispatchTouchEvent方法中默认实现return super.dispatchTouchEvent方法,父类的dispatchTouchEvent方法会去调用当前ViewGroup的onInterceptTouchEvent方法,同时ViewGroup的onInterceptTouchEvent方法默认实现返回false,时间继续向下传递。那么View的dispatchTouchEvent方法又是如何实现的呢?

同样的道理,return true 或者 return false都不能达到把事件交给View的onTouchEvent方法处理。View的dispatchTouchEvent方法默认实现调用super.dispatchTouchEvent方法的默认实现就是调用自己的onTouchEvent方法。

接下来再对上述6个结论,再做一层归类性的总结。
1.dispatchTouchEvent进行事件分发,事件分发的目标对象有哪些。
ViewGroup的dispatchTouchEvent的分发:
①return true事件被当前ViewGroup消费,终止传递。目标对象:自己
②return false事件不被当前ViewGroup消费,但终止向下传递、进行向上回溯,调用上层View的onTouchEvent。目标对象:上层View
③return super.dispatchTouchEvent方法,调用当前ViewGroup的onInterceptTouchEvent,默认事件继续向下传递。目标对象:下层View

④return super.dispatchTouchEvent方法,调用当前ViewGroup的onInterceptTouchEvent,重写onInterceptTouchEvent的返回值,返回true,交给当前ViewGroup的onTouchEvent处理。目标对象:自己,但自己有能力决定事件是否被消费。

View的dispatchTouchEvent的分发:
①return true事件被当前View消费,终止传递。目标对象:自己
②return false事件不被当前View消费,但终止向下传递(其实也不会向下传递)、进行向上回溯,调用上层View的onTouchEvent。目标对象:上层View
③return super.dispatchTouchEvent方法,调用当前View的onTouchEvent方法。目标对象:自己,但有能力决定是否真正消费事件,或者向上层View进行回溯。

2.onTouchEvent方法进行事件处理的分类:
ViewGroup和View的onTouchEvent的事件处理是一致的:
①return true,事件被当前ViewGroup或者View消费,事件终止。
②return false,事件未被当前ViewGroup或者Veiw消费,向上回溯上层ViewGroup的onTouchEvent。View的默认实现是不消费的,所等同于调用super。(TODO:继续推敲)

3.onInterceptTouchEvent对事件拦截的两种情况(只要ViewGroup有)
①return true 被拦截,交给自己的onTouchEvent进行处理,有能力真实被自己处理或者向上层ViewGroup进行回溯。
②return false不拦截,事件继续向下层View进行传递,调用下层View的dispatchTouchEvent方法。
ViewGroup的默认实现不拦截的,所以return false 等同于 return super.onInterceptTouchEvent.

到此,Touch事件分发之ACTION_DOWN事件的分发流程的主线结论,就已经完全阐述完毕。在上述的阐述中,我们给出了6个基础结论和以三个核心方法为维度的分类性结论。并且只是对这些结论做了简单的分析,旨在让大家在脑海中先形成事件分发流程知识体系的结构化。

建议,阅读此文的小伙伴们,先从道理上去想,或者从如果你来设计事件分发体系上,去领悟这些结论为什么是正确的。下一篇,我们会从源码的角度来分析和验证以上ACTION_DOWN事件分发的结论。
下面是我的个人公众号二维码,欢迎关注:

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hymKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值