如果是down事件,开始下面逻辑
(--递归开始点-) 首先调用vieGroup的dispatchTouchEvent方法,如果是down事件,则清空上次处理该事件的对象(为了处理MOVE之类的事件,做的缓存)mMotionTarget = null;
调用onInterceptTouchEvent方法,这个方法只有ViewGroup类有,具体view没有,该方法的作用是判断是否需要拦截该消息,如果返回的是true,那么消息传递结束,调用该view对象的onTouchEvent方法。如果返回的是false,说明该view没有消费事件,继续往下走
因为触摸事件是窗口坐标值,所以需要将坐标值转换为view自己的坐标体系。
转换结束后,使用for循环遍历,该view的所有子view,读取子view的坐标体系,即子view所占的大小,是个Rect对象,上下左右,拿到这个值后,根据上面转换好的坐标,判断点击的坐标是否包含在当前子view中,如果不包含,直接开始下一个子view
如果坐标包含在子view中,则调用子view的dispatchTouchEvent,如果子view还是ViewGroup类型的,那么开始从上面标有(--递归开始点-)处递归调用。如果是具体view,则调用具体view的dispatchTouchEvent,这个方法比较简单,首先判断是否通过setTouchEventListener设置值,如果设置了,那么调用onTouch方法,如果该方法返回的是ture,则直接返回,不在调用该view的OntouchEvent方法,如果返回false,则调用该view的OntouchEvent方法。并把该方法当作dispatchTouchEvent的返回者返回。
具体view的dispatchTouchEvent处理结束后,子view的dispatchTouchEvent 如果返回的是true,该view的父view会将该view对象保存到mMotionTarget,同时结束到本次down事件,如果放回的是false,则继续for循环(个人此时可以推出for循环,因为感觉没用,难道是担心有view覆盖的原因吗),开始下一个子view
(--递归结束点-)for结束后(由于该过程是同步的,所以在执行这个过程中不会有其他的事件发送过来),判断mMotionTarget是否为空,如果为空,说明没有找到目标子view,所以调用当前view(一定是ViewGroup对象的,而且是循环体所在的view对象)的super.dispatchTouchEvent方法,这个是View基类的,实现和具体view的处理逻辑一样,首先判断是否通过setTouchEventListener设置值,如果设置了,那么调用onTouch方法,如果该方法返回的是ture,则直接返回,不在调用该view的OntouchEvent方法,如果返回false,则调用该view的OntouchEvent方法。并把该方法当作 dispatchTouchEvent的返回者返回 ,交给该ViewGroup的dispatchTouchEvent 的for循环(递归调用结束一个),这就说明,如果所有的子view不消费事件,那么view会消费该事件,不管onInterceptTouchEvent的返回结果是ture还是false。同时结束本次事件。
至此,一个Down事件就处理结束,处理结束后会通知WMS,此时WMS开始派发下一个事件。
如果过来的事件是move或者up事件,首先判断down处理逻辑得到mMotionTarget是否为空,也就是说down处理中,是否找到的接收事件的子view。如果为空:说明没有找到目标子view,所以调用当前view(一定是ViewGroup对象的,而且是循环体所在的view对象)的super.dispatchTouchEvent方法,这个是View基类的,实现和具体view的处理逻辑一样, 首先判断是否通过setTouchEventListener设置值,如果设置了,那么调用onTouch方法,如果该方法返回的是ture,则直接返回,不在调用该view的OntouchEvent方法,如果返回false,则调用该view的OntouchEvent方法。并把该方法当作 dispatchTouchEvent的返回者返回 ,交给该ViewGroup的 dispatchTouchEvent 的for循环(递归调用结束一个),这就说明,如果所有的子view不消费事件,那么view会消费该事件,不管onInterceptTouchEvent的返回结果是ture还是false。同时结束本次事件
如果不为空,这个时候mMotionTarget 的直接的直接父类只走dispatchTouchEvent事件,但是mMotionTarget 的爷爷及老爷还会走dispatchTouchEvent 和onInterceptTouchEvent事件,暂时没弄明白,有明白的解释一下,谢谢。那么本次的move和up事件继续由该子view处理,这样的逻辑我们可以想到,因为同一个事件,应该有同一个view处理,而不是down事件是一个view处理,move和up事件是一个view处理。所以不为空的情况下,直接由mMotionTarget的dispatchTouchEvent处理去。
同时我们知道,在activity中还可以注册ontouchEventListener,那么他什么时间执行了?他执行的时间就是在view中没有找到消费该事件的view时,则交给acitivity去处理
到此,事件处理就分析结束,也该下班了,下周要开始干活了,PM给任务了!!,以后有时间在学习源码吧!!!!
总结:
如果父view的onInterceptTouchEvent返回的是ture,那么子view永远拿不到touch事件,同时子view的onclick事件也不会处理,因为onclick事件是在view的ontouch事件中根据条件调用的,同时如果重新view的ontouchEvent方法,而没有调用super.OntouchEvent.那么onclick事件也不会处理
如果给一个view设置了onTouchEventListener,同时设置了OnclickListener,而在onTouchListener的onTouch方法返回的是true,这个时候onClick事件不走,因为这个时候不调用onTouchEvent方法,而系统调用onclick事件在onTouchEvent中捕获到up事件时,根据条件判断执行的