View事件分发(三) - 事件分发机制二(理论分析)
1. 概述
上篇文章中记录了 View事件分发的整体流程,上篇文章是针对 View的点击事件,也就是Down事件分发来分析的,这篇文章主要记录View在 Move、Up下如何进行事件分发;
2. 具体场景
情况一:当 dispatchTouchEvent进行事件分发时,如果Action_Down返回true,是可以接收到Action_Move、Action_Up事件的,且传递规则和 Down事件一样,如下图所示
图示:
黑色代表 Down事件传递
橙色代表 Move、Up事件传递:
结论:
任何的View(或者ViewGroup)在 Down事件 返回 true,表示消费事件,同一系列后续事件(指的是Move、Up事件)也到 这个 View 就停止事件传递,传递规则和 Down事件一样;
情况二:当 dispatchTouchEvent 进行事件分发时,如果Action_Down返回false,就直接调用父View的 onTouchEvent,并且结束事件的分发,不会传递给 子View了,Move、Up事件也就不能向下传递;
图示:
黑色代表 Down事件传递
橙色代表 Move、Up事件传递:
结论:
任何的View(或者ViewGroup) 只要 onTouchEvent 的 Action_Down事件 返回 false或者super(false = super),就不会接收同一系列后续事件,也就是不会接收Move、Up事件;
情况三:如果在 ViewGroup 的 onTouchEvent 的 Down事件中消费事件
图示:
黑色代表 Down事件传递
橙色代表 Move、Up事件传递:
结论:
View 的 onTouchEvent 在 Down 中返回了 false,表示不再接收后续其他事件(指的是不再接收Move、Up事件),并且 ViewGroup的 onInterceptTouchEvent 也只是在 Down 事件时 被调用 ,其他事件不会调用(指的是Move、Up事件不会调用);
3. 结论
通过上边分析,可以得出以下结论:
1>: dispatchTouchEvent
返回 true和super,Move、Up事件和Down事件传递规则一致;
返回 false,将 不会收到 同一系列 Move、Up事件;
2>: onInterceptTouchEvent 只会接收到 Down 事件;
3>: onTouchEvent
返回 true,Move、Up事件 和 Down 事件传递规则一致;
返回false,将 不会收到 同一系列 Move、Up事件;
总结其实就是一句话:如果你需要 Down事件,就全都返回true,后续的 Move、Up事件都会给你,如果返回false,你就不会接收到后续的 Move、Up事件了;
4. 补充
补充1:
前边说过 Down__>Move__>Up 是一系列事件,这里其实还有一个 Cancel事件,如果一个 View只是收到 Down事件,没有收到完整的 一系列事件(Move、Up),此时会产生一个 Cancel事件;
关于Cancel事件 什么时候执行,如何执行,可以百度下;
补充2:
子View 可以 影响父View是否拦截行为的,在 子View 的 dispatchTouchEvent增加一行代码即可,getParent().requestDisallowInterceptTouchEvent(true),表示 请求父 View 不要拦截事件,这句代码效果不是修改 父View 对本次事件是否拦截,而是影响后续的事件:
比如 子View 在 Down事件中调用 这行代码,那么在 后续的 Move、Up事件到达 父View 时 , 父View 就不会拦截了,所以这行代码只会影响 Move、Up事件,不会影响 Down 事件;