作过android乃至作过UI开发的IT从业者大都接触过这个名词,顾名思义,即一系列事件的分发,这里咱们将细致的探讨下android端的触摸事件的分发机制。android
android事件分发,度娘上一抓一大把,为何我还要写这篇博客?这是个好问题,我看过很多相关的博文,也看过相应书籍对“事件分发”的解释,但可能入门不久,以前一直没领悟透彻,一些文章也没让我细致的体悟到个钟原因,疑问有:服务器
MotionEvent.ACTION_DOWN
事件返回true的话,以后的全部事件都没法处理了?view
消耗了点击事件,那么以后的该系列事件就都由该view
消耗了?View#requestDisallowInterptTouchEvent(false)
又能将事件的处理权交出去呢?我带着上面两个问题去翻看了ViewGroup#dispatchTouchEvent(MotionEvent ev)
的源码。函数
首先看下部分源码:阿里云
onInterceptTouchEvent(ev)
的触发条件,故而,途中2507和2508两行的条件是咱们须要关注的重点,当触摸事件类型为
ACTION_DOWN
或者
mFirstTouchTarget != null
时会进入是否拦截的判断,这里注意若是不知足上述条件时,第2519行代码
intercepted = true
,也就是说若是不是down事件的同时,
mFirstTouchTarget == null
那么该次事件交由当前ViewGroup处理。那么重点来了,
mFirstTouchTarget
是什么?是如何赋值的?
接着看:spa
MotionEvent.ACTION_DOWN,MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_HOVER_MOVE
事件的时候
dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)
将事件分发给子view处理,如果子view的处理结果返回true则进入8-28行的逻辑并会
break
跳出
for循环
,
(敲黑板)重点来了,26行
newTouchTarget = addTouchTarget(child, idBitsToAssign);
进入
addTouchTarget
方法,即图中39-44行,至此
mFirstTouchTarget
的赋值咱们理出来了。
那么有什么用呢?接着看循环外面的逻辑:3d
!=null
,所以如果子view没有消耗事件,则进入2643行,当前view去处理该事件。并最终在函数末尾
return handled
。
至此能够对问题1,作出合理的解释了。当子view不消费MotionEvent.ACTION_DOWN
事件的时候,那么在MotionEvent.ACTION_DOWN处理结束后mFirstTouchTarget是为null的
,而后该系列事件的move
等事件进入分发阶段的时候,便会在图一的2507和2508行的if校验中进入2519行intercepted = true
始终拦截事件再也不分发出去。至于问题2,问题3,其实也大都涵盖在上述分析中,聪明的小伙伴们,能够自行总结一波code
亲情推荐使用阿里云服务器,实惠稳定 附赠优惠礼包自取: 阿里云飞机票orm
本人才疏学浅,如有不足,或是胡言乱语之处,望海涵并加以斧正。cdn