写一遍加深记忆 Android的事件分发处理流程

  1. onInterceptTouchEvent()与onTouchEvent()的机制:  
  2.   1. down事件首先会传递到onInterceptTouchEvent()方法  
  3.   2. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理  
  4.   3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。  
  5.   4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理  
  6.   5. 如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。
以上官方解释,标准


对于安卓的事件分发,我理解如下观点

ViewGroup 有 dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
View  只有 dispatchTouchEvent、onTouchEvent,因为 onInterceptTouchEvent是ViewGroup 的函数




假如A ViewGroup,包含View B,那么一次默认正常的按下事件执行流程如下
A dispatchTouchEvent》A  onInterceptTouchEvent》B dispatchTouchEvent 》B onTouchEvent ,
其实 dispatchTouchEvent 的 super.dispatchTouchEvent(ev) 特别关键,因为他是调用该类的  onInterceptTouchEvent、onTouchEvent 方法。
由此可见,真实的 按下事件流程如何: A (super前)dispatchTouchEvent》A  onInterceptTouchEvent》B (Super前)dispatchTouchEvent 》B onTouchEvent 》B (super 后)dispatchTouchEvent 》A (super后)dispatchTouchEvent。












默认情况下,就是A类 对事件不作任何修改
如果在 B类中事件也没处理,就是均是false, 这个时候父类即入口的 super.dispatchTouchEvent 就是false,于是对于松手Up\move 等 事件,就不会继续给该控件了,因为他的dispatchTouchEvent 返回false,(意思就是我不需要你这些触摸事件了)


如果B的 dispatchTouchEvent 返回true,就是说 你的事件我有关注,我需要触摸事件,于是up 、move  都会接受,对于B类 什么时候会返回true呢?onTouchEvent 事件返回true,和人为地dispatchTouchEvent返回true 均可。事件都会传递到 dispatchTouchEvent中,当然是否传递到 onTouchEvent 还需要靠super.dispatchTouchEvent的调用。只要B中的dispatchTouchEvent 返回true,都是说明B 需要关注事件的。


如果B dispatchTouchEvent 返回true ,那么对于A dispatchTouchEvent 就是也就会是返回true,就是说明这次Activity的事件,这个组件有处理;








对于A类
onTouchEvent 方法时候调用呢?前提是 dispatchTouchEvent 中的super.dispatchTouchEvent有执行,不过还需要 onInterceptTouchEvent 方法返回true 来拦截给该View 处理,不然会传递到下一个子View的,如果此时子View onTouchEvent 返回false,不处理事件,那么也会调用父控件的 onTouchEvent 方法;
如果A类 onInterceptTouchEvent 拦截了事件,那么B类就不会收到如何事件传递, 那拦截了谁来处理呢?当然是A的onTouchEvent 方法,如果onTouchEvent 返回true,说明消费了该事件,于是A的dispatchTouchEvent 就会返回true,给上层说有关注了该触摸事件,如果 拦截了,但是 onTouchEvent  却返回false,说明了 A只是拦截了事件,却对事件不感兴趣或者不符合A的要求事件,于是 super.dispatchTouchEvent 会返回false。于是 后续的up、move均不传递进来A ;








结论
 dispatchTouchEvent 方法是一个分发的意思,并且里面的super.dispatchTouchEvent 是会执行onInterceptTouchEvent、onTouchEvent方法 和子View 的dispatchTouchEvent 等。如果这个函数返回true,说明有控件关注这个事件,自身或者是 子View,于是后续的事件up、move 就会传递过来;否则就不接受后续事件了;




onInterceptTouchEvent 只是ViewGroup 的拦截方法,但是是否消费是在onTouchEvent 中,ViewGroup必须先拦截才有消费的可能,如果当前ViewGroup拦截并处理了,对于后续的up、move事件不再需要拦截,但是父ViewGroup流程继续走;




View 中的消费也是onTouchEvent ,因为他没子View,所以不需要拦截,只需要判断是非消费即可
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值