事件分发的流程
三个函数
-
dispatchTouchEvent 事件分发,事件处理
-
onInterceptTouchEvent 事件拦截
-
onTouchEvent 事件消费
1.从当前的Activity开始,开始分发事件
2.调用它的window,即PhoneWindow进行事件分发,phoneWindow再分发给mDecor
就是一个FrameLayout
3.因为frameLayout是一个viewGroup,调用viewGroup的dispatchTouchEvent
mFirstTouchTarget是一个链表,存储了事件的目标view
disallowIntercept标识了子view是否允许父view拦截
简单理解版流程,先判断子view是否允许你拦截,允许了,再问自己的拦截器(onInterceptTouchEvent)是否要拦截(绝大部情况都不会拦截),不要拦截,就分发给自己的子view(这个过程是一个递归),当分发给所有的子view而且没有消费事件时,再询问自己是否要进行消费
viewGroup和view中不同任务
view中的dispatchTouchEvent 用来事件处理,onTouch事件消费
view的处理事件
一般有两种处理,点击事件和触摸事件
下图会同时打印,如果onTouch返回true就不会打印onClick,onTouch返回true会消费事件
ViewGroup中的dispatchTouchEvent分发流程
判断子View是否有能力处理
分发事件,分发成功则调用孩子的dispatchTouchEvent
头插法,往链表中加入target
mFirstTouchTarget!=null,handled变为true
什么叫事件冲突:事件只有一个,多个人想要处理--处理的对象不是我们想给的对象
只能在move的时候处理冲突
内部拦截法:子view处理事件冲突
调用子view的requestDisallowInterceptTouchEvent方法 设置它的 disallowIntercept为true,不允许父view拦截
外部拦截法:父View处理冲突
调用父View的onInterceptTouchEvent方法返回true,拦截子view的事件
move的过程中
父view可以抢子view的事件,子view不能抢父view的事件