写一遍加深记忆 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,所以不需要拦截,只需要判断是非消费即可
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,所以不需要拦截,只需要判断是非消费即可
相关文章推荐
- Android 触摸事件的分发与处理流程:onInterceptTouchEvent和onTouchEvent
- android的事件分发处理流程
- 浅谈android 点击事件分发处理流程
- Android View 事件分发处理流程
- Android事件处理分析+Android事件处理 +Android输入事件流程
- Android的frameworks层键盘事件处理流程分析
- android 屏幕触摸事件的分发与处理
- Android中的Touch事件处理流程
- Android_事件的分发与处理机制及解决事件冲突问题
- 【转】Android事件处理流程
- Android事件处理分析+Android事件处理 +Android输入事件流程
- android的frameworks层键盘事件处理流程分析
- android中事件的分析(触发以及分发处理)
- Android热插拔事件处理流程--Vold
- Android热插拔事件处理流程--Vold
- Android中ListView的onKeyDown、onKeyUp、onKeyMultiple事件的处理流程
- android View 事件处理流程
- Android事件处理流程
- Android 事件捕捉和处理流程分析
- Android之Input子系统事件分发流程