转载请标明出处!http://blog.csdn.net/sahadev_/article/details/23839039 ,当然一般也没人转载。。。
一直想彻底了解View的事件分发过程,在网上也看了很多大神的博客,但是总有一些东西不是很明白,于是自己就根据源码画了一个流程草图,思路总算是清晰了。
文章分为View和ViewGroup两部分介绍,首先来讲讲View的事件分发:
打开View的源码,顺着onTouch方法向上找到dispatchPointerEvent(MotionEvent event)的这个方法,在View中再没有其它地方调用它,估计事件就是从这里传过来的吧。
来贴一下这个方法的源码:
看到在这个方法中调用了dispatchTouchEvent的这个方法,dispatchTouchEven()暂时没找到它的相关说明,权当它返回了true,进入dispatchTouchEvent方法:
可以看到在这个方法中调用了onTouchEvent(Event),所以可知onTouchEvent(event)是由dispatchTouchEvent触发的。如果有人对onFilterTouchEventForSecurity这方法有疑问,API中是这么解释的:True if the event should be dispatched, false if the event should be dropped.这句话就不用翻译了吧,相信大家都懂。
如果onTouchEvent返回了true,那么dispatchTouchEvent的返回值也为true. 对于dispatchTouchEvent的返回值说明是这么解释的:True if the event was handled by the view, false otherwise. 如果返回true,说明这个事件就被当前的这个View消费掉了,这里的返回值大家一定要清楚,一会在ViewGroup的说明中需要对这块很熟悉。
接下来说一说ViewGroup的事件分发方法:
ViewGroup的事件处理相对View相对有些复杂,ViewGroup继承于View,在View中dispatchTouchEvent是由dispatchPointerEvent触发的,所以ViewGroup也是由dispatchPointerEvent触发的,这里不重要,接着看ViewGroup的dispatchTouchEvent的源代码:
ViewGroup的dispatchTouchEvent的方法有些长,在代码中可以看到,ViewGroup将View的该方法彻底重写了,没有很明显的看到super.dispatchTouchEvent的字样,也就是说还没有着急把事件交给View去处理。
前几行和View都差不错,往下看
在第5行中调用了onInterceptTouchEvent(ev);该方法表示当按下事件触发的时候是否要拦截本次事件,这个方法的源码是这样的:
如果不对它进行重写的话,它总是返回false,也就是说intercepted的值恒为false,接着往下看,看到 if (!canceled && !intercepted) {这一行的时候,由于intercepted为false,所以事件可以进入if内执行,接着往下看:
看到这段代码中dispatchTransformedTouchEvent的这个方法开始对ViewGroup的子View进行事件传递了:
该方法的最终返回值是布尔值,意思为是否被处理了,请看这里:
这里开始对子View进行事件传递,调用子View的dispatchTouchEvent的方法,如果被子View消费掉了本次事件,dispatchTransformedTouchEvent就返回true,再回到那个循环:
请注意这个方法:
这个方法中的代码是这样的:
注意将mFirstTouchTarget赋了值,不再是null,先记住这里,待会有用。
好了,子View循环完成之后,代码会执行到这里:
注意到刚刚mFirstTouchTarget被赋了值,不再是null,不为null,就不会执行if中的语句,if中的语句都做了些什么呢?
注意第3个参数是Null,咱们再返回到dispatchTransformedTouchEvent中(刚才已经贴过方法内的代码):
该方法内有3处super.dispatchTouchEvent(event);因为刚才mFirstTouchTarget的值不为null,所以没有进入if,所以ViewGroup没法去调用super.dispatchTouchEvent(event);所以当子View把事件消费完成之后,ViewGroup就无法接收到onTouchEvent事件,这就是为什么子View返回true,ViewGroup就无法处理的原因。
事件传递到这里也就讲完了,不知道大家有没有听明白,如果有什么疑问可以在下面留言,欢迎转载!