Android 事件分发 简单学
2018-08-15 11:07
337 查看
本文地址:https://my.oschina.net/lifj/blog/1928132
onInterceptTouchEvent(只有ViewGroup有)
onTouchEvent(View 和 ViewGroup都有)
从上图可以看到:dispatchTouchEvent的返回值可能是由两部分决定的:自身的touchEvent返回值,或者子view的dispatchTouchEvent的返回值。
对于ViewGroup来说:根据onInterceptTouchEvent的返回值,决定调用自身的onTouchEvent还是分发到子view里面。
对于View来说:直接调用onTouchEvent。
onInterceptTouchEvent:
告诉dispatchTouchEvent是不是需要分发下去(也就是被拦截)
onTouchEvent:
自身的处理
怎么知道没有控件去处理呢?就是通过dispatchTouchEvent的返回值判断的:
返回false,说明没有view需要处理事件。
返回true,说明有View需要处理。对于View,就是自己需要处理。对于ViewGroup,可能是子View需要处理,也可能是自己需要处理。
当返回true之后,ViewGroup中会记录需要处理的View的对象,作为targetChild。否则的话targetChild为null。
返回true的情况,第一个调用的还是dispatchTouchEvent,上一次Down事件记录了targetChild,那么就会直接调用targetChild的dispatchTouchEvent。如此调用下去,直到return true。
也就是说:事件会被放到Activity的Looper中。
然后从Looper中取出,传给ViewRootImpl,入队。
ViewRootImpl中的deliver去传递事件给View,给Activity,给DocerView.
(启动Activity会创建ViewRootImpl和PhoneWindow,建立起与WMS(window manager service)的连接)
Android 事件分发过程
网上有很多这样的文章,我又写了一篇,希望能够清晰明了的告诉大家整体的事件分发过程,而不是一脸懵逼的进来,一脸懵逼的出去。三个事件
dispatchTouchEvent (View 和 ViewGroup都有)onInterceptTouchEvent(只有ViewGroup有)
onTouchEvent(View 和 ViewGroup都有)
事件的调用流程图
从上图可以看到:dispatchTouchEvent的返回值可能是由两部分决定的:自身的touchEvent返回值,或者子view的dispatchTouchEvent的返回值。
整体分发思路 -- 伪代码
/* * 事件分发的伪代码 */ public class Layout extends ViewGroup{ private View targetChild = null;//记录DOWN事件找到的目标view,作为后续事件的分发对象。 public boolean dispatchTouchEvent(MotionEvent event){ if(this instanceof ViewGroup){ //DOWN的时候targetChild为null。其他后续事件不为null。 if(targetChild != null){ //MOVE,UP,CANCEL等事件直接dispatch过去。 return targetChild.dispatchTouchEvent(event); } //DOWN的时候会走以下逻辑 boolean interceptRet = this.onInterceptTouchEvent(event); if(interceptRet == true){ //拦截,调用自身的onTouchEvent,并返回 return this.onTouchEvent(event); }else if(interceptRet == false){ //不拦截,遍历子View for(int i = 0 ;i< getChildCount();i++){ targetChild = getChildAt(i); //判断是不是目标View if(targetChild.dispatchTouchEvent(event)){ //dispatchTouchEvent返回true,说明是。并返回 return true; }else{ //否则不是 targetChild = null; } } //没有找到targetView,调用自身的TouchEvent,并返回 if(targetChild == null){ return this.onTouchEvent(event); } } }else if(this instanceof View){ //View直接走自己的onTouchEvent return this.onTouchEvent(event); } return false; } }
各自的作用
dispatchTouchEvent:对于ViewGroup来说:根据onInterceptTouchEvent的返回值,决定调用自身的onTouchEvent还是分发到子view里面。
对于View来说:直接调用onTouchEvent。
onInterceptTouchEvent:
告诉dispatchTouchEvent是不是需要分发下去(也就是被拦截)
onTouchEvent:
自身的处理
Down 与其他事件
Down事件的特殊之处
Down事件作为Event的第一个事件,担任的重任就是找到需要处理Event的控件。如果Down分发一遍之后没有找到需要处理事件,那么这个消息就不会再传到这些View(ViewGroup)中了。怎么知道没有控件去处理呢?就是通过dispatchTouchEvent的返回值判断的:
返回false,说明没有view需要处理事件。
返回true,说明有View需要处理。对于View,就是自己需要处理。对于ViewGroup,可能是子View需要处理,也可能是自己需要处理。
当返回true之后,ViewGroup中会记录需要处理的View的对象,作为targetChild。否则的话targetChild为null。
其他事件
根据Down事件的返回结果,返回false的话,后续其他的事件都不会分发下来。返回true的情况,第一个调用的还是dispatchTouchEvent,上一次Down事件记录了targetChild,那么就会直接调用targetChild的dispatchTouchEvent。如此调用下去,直到return true。
事件的来源
android.os.Looper.loop(Looper.java:136) 取出消息 InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185) android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6188) android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3859) android.view.View.dispatchPointerEvent(View.java:10244) android.app.Activity.dispatchTouchEvent(Activity.java:3065) com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1808) com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:416) android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2264)
也就是说:事件会被放到Activity的Looper中。
然后从Looper中取出,传给ViewRootImpl,入队。
ViewRootImpl中的deliver去传递事件给View,给Activity,给DocerView.
(启动Activity会创建ViewRootImpl和PhoneWindow,建立起与WMS(window manager service)的连接)
相关文章推荐
- Android事件总线分发库EventBus3.0的简单讲解与实践
- 更简单的学习Android事件分发
- android 事件分发机制,最简单详解
- Android事件分发与处理简单整理
- Android事件总线分发库EventBus3.0的简单讲解与实践
- 更简单的学习Android事件分发
- 更简单的学习Android事件分发
- 一个android事件分发的简单Demo
- android 点击事件分发简单介绍
- Android事件总线分发库EventBus3.0的简单讲解与实践
- 更简单的学习Android事件分发
- 更简单的学习Android事件分发
- Android与javascript中事件分发机制的简单比较
- Android事件分发简单理解
- Android 事件拦截机制、事件分发机制简单分析
- Android View事件分发和消费源码简单理解
- Android的Touch事件分发机制简单探析
- Android的Touch事件分发的简单应用举例
- 【转载】更简单的学习Android事件分发
- 【Android事件分发】从简单的onTouch理解Android事件分发