android开发-事件分发详解

事件分发源码分析
事件最先传递个当前的Activity,由Activity的dispatchTouchEvent来进行时间派发
具体的工作由Activity内部的Window来完成的,Window会将事件传递给decorview,


decorview就是当前视图的底层容器


dispatchTouchEvent返回值为true 表示事件被他或者她的子view给消化了
如果返回false表示没有任何的view消化了 就不能设置target了 那么


public void dispatchTouchEvent(MotionEvent event){
.....
if(getWindow().superDispatchTouchEvent(event)){
return true;
}
return onTouchEvent(ev);
}
事件开始交给Activity所附属的Window进行分发 如果返回true 那么整个事件循环就结


束了,返回false意味着时间没有任何控件进行处理 ,那么就由Activity的


onTouchEvent就会被调用执行


WindowPhone是Window的实现类,那么他也实现了superDispatchTouchEvent()的抽象方


法,WindowPhone是Window唯一的实现类
而在PhoneWindow中的PhoneWindow的superDispatchTouchEvent()实现是
public void superDispatchTouchEvent(MotionEvent event){
mDecor.superDispatchTouchEvent(event);
}
那么PhoneWindow将事件直接传递给了DecorView
顶级View DecorView的分发是这样的
事件传达到ViewGroup的之后,会调用viewGroup的dispatchtouchEvent方法,
1、如果顶级ViewGroup的拦截事件即onInterceptTouchEvent的返回为true,这由事件


ViewGroup处理
如果此时viewGroup设置了setOnTouchListener,则调用他的回调onTouch,同


时屏蔽了onTouchEvent
如果没有设置setOnTouchListener,那么onTouchEvent会被调用


dispatch里面 会检测是否设置了FLAG_DISALLOW_INTERCEPT,而这个标识位是通过子View的requestDisallowInterceptTouchEvent方法调用的,这样就不会调用onInterceptTouchEvent方法了


但是对ACTION_DOWN是不起作用的,因为每次ACTION_DOWN的时候都会调用restTouchState 去重置状态
requestDisallowInterceptTouchEvent不会影响ViewGroup对ACTION_DOWN的处理




当ViewGrop决定拦截事件后,后续的时间默认交给他自己的onTouch 并且不会再调用onInterceptTouchEvent方法


如果想提前处理所有的时间,请选择使用dispatchTouchEvent方法,因为他每次都会被调用
另外一个点FLAG_DISALLOW_INTERCEPT这个对于我们解决滑动冲突提供了一个解决方案




如果ViewGroup本身不拦截事件,也就是不用自己onTouchEvent处理
那么会继续走下去,分发给他自己的子View进行处理


在源码中 回去遍历所有的子View,然后查看点击事件的坐标是否在某个子View上面以及判断动画运动的点是否在触摸点位置
如果满足这两个条件那么就调用 dispatchTransformTouchEvent,实际上就是调用子View的dispatchTouchEvent方法
如果有符合条件的,就调用addTouchTarget方法,在这里面mFirstTouchTarget被赋值了刚才的子view
如果子View的dispatchTouchEvent返回为true,那么就把mFirstTouchTarget赋值了,这样以后viewGroup就不会拦截了




View的dispatchTouchEvent方法比较简单
首先会判断有没有设置setOnTouchListener,如果有就调用OnTouchListener中的onTouch方法,如果onTouch反悔了true,那么onTouchEvent就不会被调用,因为OnTouchListener的优先级高于onTouchEvent
在onTouchEvent里面,只要View的CLICKABLE和LONG_CLICKABLE有一个为true,那么就会消耗这个时间,即onTouchEvent方法返回true,不管他是不是DISABLE状态。
在ACTION_UP时间触发时,会触发performClick方法,如果设置了setOnClickListener,那么performClick会调用onClick
如果没有符合条件的子View,那么这个点击事件就调用了super.dispatchTouchEvent交给他的父类View进行事件的处理



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值