Android事件传递机制
2016-05-19 16:30
471 查看
Android开发过程中复杂混合控件的难点之一的就是事件冲突。我们知道在处理事件冲突中,最重要的方法是:dispatchTouchEvent(),onInterceptTouchEvent(),onTouchEvent(),通过作用这三个方法,我们可以达到事件的分发、拦截、消费的效果。在activity(无onInterceptTouchEvent()),viewgroup,view中,根据返回值boolean类型,完成了事件的一系列过程。
讲到事件的传递机制,可以想象这样一个过程,技术总监有一个内容要开发,首先移交开发leader,开发leader认为组员可以完成又移交给组员,最终完成开发过程。从Android的事件分发机制来讲:开发的完成称之为事件的消费。(参考来源:http://www.open-open.com/lib/view/open1422428386548.html);开发内容完成的过程中,完成对象从技术总监到组员,我们称之为事件的分发过程。而按照上述的流程,我们仅仅是进行了向下的流程分发和消费,但也会存在事件的拦截和向上分发。我们可以理解为 :
①. 组员能力不足完成不了转交给leader,leader又出差了没办法完成还给技术总监,技术总监最后只好自己完成这个功能;
②. leader觉得这个事情对于组员有难度,于是自己完成了这件事情;
③. leader认为这个事情以自己的能力只能完成一部分,于是完成了一部分又移交给了技术总监完成。
从上述的三个流程线来讲,无论哪一种流程,都不是正常的A->B->C的过程,而是出现了A->B->A,A->B的这样一种过程,缺少了C的存在,这个时候可以称之为事件的拦截。
从代码的角度讲:Activity是A,技术总监,ViewGroup是B,leader,View是C,组员,dispatchTouchEvent方法进行了事件向上传递的拦截,onInterceptTouchEvent进行了事件向下的拦截,onTouchEvent进行了事件的消费。
根据返回值的不同,我们可以做出如下判断:
当然一个完整的动作事件中会包含许多的细节流程,如:ACTION_DOWN,ACTION_UP,ACTION_MOVE等,从ACTION_DOWN到ACTION_UP或者ACTION_CANCEL的过程其实是一个记忆过程,正如上述的流程,当组员的能力被定义为无法实现该任务的时候,那么下一次相同的task就不会移交组员来做,而是由能完成该task的leader来实现。所以当出现事件拦截的时候,ACTION_DOWN经历的事件分发流程在ACTION_UP就会直接被分发到能真正消费该action的view层被消费。省去了中间向上传递过程。
讲到事件的传递机制,可以想象这样一个过程,技术总监有一个内容要开发,首先移交开发leader,开发leader认为组员可以完成又移交给组员,最终完成开发过程。从Android的事件分发机制来讲:开发的完成称之为事件的消费。(参考来源:http://www.open-open.com/lib/view/open1422428386548.html);开发内容完成的过程中,完成对象从技术总监到组员,我们称之为事件的分发过程。而按照上述的流程,我们仅仅是进行了向下的流程分发和消费,但也会存在事件的拦截和向上分发。我们可以理解为 :
①. 组员能力不足完成不了转交给leader,leader又出差了没办法完成还给技术总监,技术总监最后只好自己完成这个功能;
②. leader觉得这个事情对于组员有难度,于是自己完成了这件事情;
③. leader认为这个事情以自己的能力只能完成一部分,于是完成了一部分又移交给了技术总监完成。
从上述的三个流程线来讲,无论哪一种流程,都不是正常的A->B->C的过程,而是出现了A->B->A,A->B的这样一种过程,缺少了C的存在,这个时候可以称之为事件的拦截。
从代码的角度讲:Activity是A,技术总监,ViewGroup是B,leader,View是C,组员,dispatchTouchEvent方法进行了事件向上传递的拦截,onInterceptTouchEvent进行了事件向下的拦截,onTouchEvent进行了事件的消费。
根据返回值的不同,我们可以做出如下判断:
/** * 事件的向上传递 * @param ev 动作对象 * @return true: 在当前的dispatchTouchEvent中消费事件,事件停止传递 * false: 拦截事件的分发,并向上传递使父View对动作事件进行了{@link #onTouchEvent(MotionEvent)}的消费和传递 * super.dispatchTouchEvent(ev): 对事件进行流程判定进入本层的 {@link #onInterceptTouchEvent(MotionEvent)} */ public boolean dispatchTouchEvent(MotionEvent ev) { return super.dispatchTouchEvent(ev); }
/** * 事件的向下传递 * param ev 动作对象 * @return true: 进行向下传递事件的拦截,并将事件传递到本层的{@link #onTouchEvent(MotionEvent)} * false: 不拦截事件的向下传递 * super.onInterceptTouchEvent(ev): 不拦截事件的向下传递 */ public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); }
/** * 事件的消费 * param ev 动作对象 * @return true: 事件已消费,不再传递 * false: 事件消费未完成,继续向上传递 * super.onTouchEvent(ev): 事件消费未完成,继续向上传递 */ public boolean onTouchEvent(MotionEvent ev) { return super.onTouchEvent(ev); }
当然一个完整的动作事件中会包含许多的细节流程,如:ACTION_DOWN,ACTION_UP,ACTION_MOVE等,从ACTION_DOWN到ACTION_UP或者ACTION_CANCEL的过程其实是一个记忆过程,正如上述的流程,当组员的能力被定义为无法实现该任务的时候,那么下一次相同的task就不会移交组员来做,而是由能完成该task的leader来实现。所以当出现事件拦截的时候,ACTION_DOWN经历的事件分发流程在ACTION_UP就会直接被分发到能真正消费该action的view层被消费。省去了中间向上传递过程。
相关文章推荐
- 避免使用非静态内部类,这会导致Context泄露
- android listview 连续调用getview问题分析及解决
- Android 4.0 事件输入(Event Input)系统
- Android 添加系统服务
- Android学习参考
- android View内容滑动的几种方式
- 为什么应该使用MyFragment.newInstance()创建新的Frgament,而不是new MyFragment()
- Android中Activity、Service和线程之间的通信
- Android通用流行框架大全
- Android并发编程线程间通信的三种基本方式
- AndroidStudio NDK开发最佳入门实践
- Activitys, Threads和 内存泄露
- Android:Ubuntu 16.04上编译Android主线最新代码
- android 线程间的通信
- [置顶] Android自定义View(一、初体验自定义TextView)
- Android自定义View(一、初体验自定义TextView)
- android开发过程一(intent_button)
- Android4.4-Launcher源码分析系列之Launcher介绍
- Android 多线程及线程通信
- android 软键盘弹出 自动调整布局