您的位置:首页 > 移动开发 > Android开发

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

2016-11-22 18:40 399 查看
onInterceptTouchEvent()与onTouchEvent()的机制:  

  1. down事件首先会传递到onInterceptTouchEvent()方法  

  2. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理  

  3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。  

  4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理  

  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,所以不需要拦截,只需要判断是非消费即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: