Android —View的事件分发机制
2016-03-28 11:19
525 查看
所谓的Android事件分发,其实就是对Android的MotionEvent事件进行处理的过程。而这个过程,Android给出了3个方法来处理。
分别是:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三个方法来完成的。
1.dispatchTouchEvent
此方法是用来进行事件的分发。当一个事件传递到当前View,那么此方法就一定会被调用。其返回值表示是否消耗掉当前的事件。
2.onInterceptTouchEvent
此方法在dispatchTouchEvent的内部调用,用来判断是否拦截某个事件。如果当前View拦截了某个事件,那么在同一个事件序列中,此方法不会被再次调用。 返回结果表示是否拦截当前事件。
3.onTouchEvent
此方法也是在dispatchTouchEvent的内部调用,是用来处理点击事件的方法。返回结果表示是否消耗掉当前事件。如果不消耗则在同一个事件序列中,当前View无法再次接受到事件。
这三个方法的关系,我们可以用一段伪代码来理解:
通过这段伪代码,我们可以大致了解到:对于一个根ViewGroup来说,点击事件首先会传递给dispatchEvent方法。这时,需要查看ViewGroup的onInterceptTouchEvent方法的返回值,(此处是分发的关健)如果该方法返回true,则表示该ViewGroup需要拦截事件,其自身的OnTouchEvent就会被调用,事件不会再向下传递。如果返回false,则表示不拦截事件,接着就会调用子View的ondispatchTouchEvent方法。如此循环下去,直到事件被最终处理掉。----------------------------------------------------------------------------当事件到达onTouchEvent之后,这是就需要看当前onTouchEvent的返回值了:如果当前View的onTouchEvent返回false,则自身放弃事件处理,那么他的父容器的onTouchEvent就会被调用。以此类推。如果所有的View都不处理,那么事件最终会返还给Activiety的onTouchEvent来处理。
如果对上述描述还是不是很理解的话,我们可以想象一下现实生活中的管理的例子:公司的老板给总经理下达一个任务(MotionEvent),总经理接收到任务(onInterceptTouchEvent),此时考虑是否自己来处理这个任务(onInterceptTouchEvent),此时他不想自己处理,于是将任务分配给自己的秘书(下级View)来处理。----------以上是向下分发---------------此时,秘书发现自己处理不了这个任务(onTouchEvent返回false)
,那么总经理只好自己来处理。而最后总经理发现自己也搞不定这个任务(onTouchEvent返回false)。老板没办法,只好自己来处理了。--------------------以上是向上返回处理--------------
通过上面的描述,我们可以大致了解,整个事件的传递过程是一个上下级关系的传递,例子中我只描述了3级关系,而这个关系是可以更多级的,然而无论多少级,这个事件传递的流程是不变的。
此处我们需要了解一下ViewGroup和子View的区别:ViewGroup默认是不拦截任何事件的,所以其onInterceptTouchEvent默认返回fasle,而View 没有onInterceptTouchEvent方法,所以一旦事件传递给它的时候,那么他的onTouchEvent就一定会被调用。(注意:如果手动将子View的onDispatchTouchEvent重写,则子View的OnTouchEvent并不会被调用(因为onTouchEvent是在其里面调用的,重写了该方法,就覆盖了调用onTouchEvent的代码了))
以后再继续补充。。。。。。。。。。。。。
分别是:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三个方法来完成的。
1.dispatchTouchEvent
此方法是用来进行事件的分发。当一个事件传递到当前View,那么此方法就一定会被调用。其返回值表示是否消耗掉当前的事件。
2.onInterceptTouchEvent
此方法在dispatchTouchEvent的内部调用,用来判断是否拦截某个事件。如果当前View拦截了某个事件,那么在同一个事件序列中,此方法不会被再次调用。 返回结果表示是否拦截当前事件。
3.onTouchEvent
此方法也是在dispatchTouchEvent的内部调用,是用来处理点击事件的方法。返回结果表示是否消耗掉当前事件。如果不消耗则在同一个事件序列中,当前View无法再次接受到事件。
这三个方法的关系,我们可以用一段伪代码来理解:
public boolean dispatchTouchEvent(MotionEvent ev){ boolean consume = false; if(onInterceptTouchEvent(ev)){ consume = onTouchEvent(ev); } else { consume = child.dispatchTouchEvent(ev); } return consume; }
通过这段伪代码,我们可以大致了解到:对于一个根ViewGroup来说,点击事件首先会传递给dispatchEvent方法。这时,需要查看ViewGroup的onInterceptTouchEvent方法的返回值,(此处是分发的关健)如果该方法返回true,则表示该ViewGroup需要拦截事件,其自身的OnTouchEvent就会被调用,事件不会再向下传递。如果返回false,则表示不拦截事件,接着就会调用子View的ondispatchTouchEvent方法。如此循环下去,直到事件被最终处理掉。----------------------------------------------------------------------------当事件到达onTouchEvent之后,这是就需要看当前onTouchEvent的返回值了:如果当前View的onTouchEvent返回false,则自身放弃事件处理,那么他的父容器的onTouchEvent就会被调用。以此类推。如果所有的View都不处理,那么事件最终会返还给Activiety的onTouchEvent来处理。
如果对上述描述还是不是很理解的话,我们可以想象一下现实生活中的管理的例子:公司的老板给总经理下达一个任务(MotionEvent),总经理接收到任务(onInterceptTouchEvent),此时考虑是否自己来处理这个任务(onInterceptTouchEvent),此时他不想自己处理,于是将任务分配给自己的秘书(下级View)来处理。----------以上是向下分发---------------此时,秘书发现自己处理不了这个任务(onTouchEvent返回false)
,那么总经理只好自己来处理。而最后总经理发现自己也搞不定这个任务(onTouchEvent返回false)。老板没办法,只好自己来处理了。--------------------以上是向上返回处理--------------
通过上面的描述,我们可以大致了解,整个事件的传递过程是一个上下级关系的传递,例子中我只描述了3级关系,而这个关系是可以更多级的,然而无论多少级,这个事件传递的流程是不变的。
此处我们需要了解一下ViewGroup和子View的区别:ViewGroup默认是不拦截任何事件的,所以其onInterceptTouchEvent默认返回fasle,而View 没有onInterceptTouchEvent方法,所以一旦事件传递给它的时候,那么他的onTouchEvent就一定会被调用。(注意:如果手动将子View的onDispatchTouchEvent重写,则子View的OnTouchEvent并不会被调用(因为onTouchEvent是在其里面调用的,重写了该方法,就覆盖了调用onTouchEvent的代码了))
以后再继续补充。。。。。。。。。。。。。
相关文章推荐
- 史上最详细的Android Studio系列教程二--基本设置与运行
- Android 自定义控件打造史上最简单的侧滑菜单
- 史上最详细的Android Studio系列教程三--快捷键
- Android Studio报错Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVE
- Android应用构架
- android头像选择(拍照,相册,裁剪)
- dashed-circular-progress——Android动画圆环进度条控件
- android头像选择(拍照,相册,裁剪)
- 史上最详细的Android Studio系列教程四--Gradle基础
- Android spinner的默认状态的保存
- Android Studio系列教程五--Gradle命令详解与导入第三方包
- Android Studio Tips -- 布局预览
- 在AndroidStudio中配置Gradle进行 “动态编译期间,根据远程服务器地址 ,生成多类安装包”
- Android 用Animation-list实现逐帧动画
- Android Studio中使用AIDL进行进程间通信
- Android Studio中 常用快捷键清单
- Android 高仿 QQ5.0 侧滑菜单效果
- Android的消息机制之ThreadLocal的工作原理
- Android中ListView.getCount()与ListView.getChildCount()区别和OnScrollListener()各个参数的区别
- 初涉RxAndroid结合Glide实现多图片加载操作