一张图让你了解安卓事件处理流程的走向
2015-12-02 11:57
676 查看
转载请标明出处:http://blog.csdn.net/qq1940879801/article/details/50136965
最近小明遇到问题老是问我,其中有一个问题是这样的:
小明:在ScrollView嵌套ListView,ListView无发滑动
一看就知道他不懂安卓事件处理机制,然后我耐心帮他讲解,最后虽然他懂了,但是我还是觉得有必要总结下安卓事件处理机制。
一.什么是事件
事件就是对触摸屏幕的操作,比如触摸事件,单机事件,滑动事件等。
用户对触摸屏幕的所有操作,都是先按下去,最后弹起来,按下去的时候可以进行一段移动,再弹起来,也就是说说有基本事件都包括这三种事件状态:
按下(ACTION_DOWM)
移动(ACTION_MOVE)
弹起(ACTION_UP)
安卓为响应这些事件,提供一个类MotionEvent,其中有这样一句话:
Motion events are always delivered to views as a consistent stream of events. What constitutes a consistent stream varies depending on the type of device. For touch events, consistency implies that pointers go down one at a time, move around as a group and
then go up one at a time or are canceled.
翻译:请求事件总是依照一个始终如一的事件流传递给视图。什么是一个始终如一的流变化取决于设备的类型。对触摸事件,一致性意味着指针走一次,作为一个整体移动,然后向上一次或被取消。
也就是说事件从点击的子视图(View)开始,向上传递事件给父视图(ViewGroup),一直传递到传递到Activity。
而安卓的事件处理流程则是由Activity的dispatchTouchEvent,再到ViewGroup的dispatchTouchEvent,再到Viewgroup的onInterceptTouchEvent,一直传递到点击的子视图View
二.view的事件分发以及viewgroup的事件分发和拦截
通过查看view的源码,发现view只有dispatchTouchEvent,OnTouchEvent
通过查看Viewgroup的源码,发现viewgroup不仅有dispatchTouchEvent,OnTouchEvent,还有onInterceptTouchEvent
dispatchTouchEvent:方法用于事件的分发,Android中的所有事件都必须经过此方法的分发,然后决定是自身消费当前事件还是继续向下分发给 视图处理。返回true表示不在继续分发,事件被消费了。返回false则事件继续分发,如果是viewgroup则分发给onInterceptTouchEvent进行判断是否拦截
OnTouchEvent:方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。
onInterceptTouchEvent:是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的
三.从一个案例让你了解事件执行流程
案例1:view的事件分发
1.自定义类JesseButton继承Button
2.重写dispatchTouchEvent和onTouchEvent方法
res/layout/activity_main.xml文件如下
输出结果:
温馨提示:这里鼠标要稍微滑动下,才能响应事件的移动状态(即才会有ACTION_MOVE)
由此可以看出,View事件执行流程是:
(Activity)dispatchTouchEvent-->(Button)dispatchTouchEvent-->(Button)onTouch-->(Button)onTouchEvent
案例2:viewgroup的事件分发和事件拦截
在原来基础上新增一个类JesseLinearLayout
res/layout/activity_main.xml文件改为如下
运行结果:
由此可以看出,Viewgroup事件执行流程是:
(Activity)dispatchTouchEvent-->(LinearLayout)diapatchTouchEvent-->(LinearLayout)onInterceptTouchEvent-->(Button)dispatchTouchEvent-->(Button)onTouch-->(Button)onTouchEvent
四.一张图让你了解事件处理流程的走向
默认执行流程是
(Activity)dispatchTouchEvent(ACTION_DOWM返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_DOWM返回false)-->(LinearLayout)onInterceptTouchEvent(ACTION_DOWM返回false)-->(Button)dispatchTouchEvent(返回false)-->(Button)onTouch(返回false)-->(Button)onTouchEvent
假如在(LinearLayout)diapatchTouchEvent的ACTION_DOWM返回true,三种状态执行的事件是:
ACTION_DOWM状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_DOWM返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_DOWM返回false)
ACTION_MOVE状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_MOVE返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_MOVE返回false)-->(LinearLayout)onInterceptTouchEvent
ACTION_UP状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_UP返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_UP返回false)-->(LinearLayout)onInterceptTouchEvent
如果我们不想ACTION_UP状态的(LinearLayout)onInterceptTouchEvent执行,只需要(LinearLayout)diapatchTouchEvent(ACTION_UP返回true)即:
ACTION_UP状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_UP返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_UP返回true)
五.解释和总结:
继续重复-----事件包括最基本的三种状态:按下(ACTION_DOWM),移动(ACTION_MOVE),弹起(ACTION_UP)
1.我们单击view,这时候事件由view通过MotionEvent向上传递事件,先传递给ViewGroup再通过MotionEvent向上传递事件,直到Activity
2.事件默认处理流程则相反,由Activity的dispatchTouchEvent向下传递事件,先传递给ViewGroup的dispatchTouchEvent,再传递给ViewGroup的onInterceptTouchEvent,最后传递到View的dispatchTouchEvent
3.由dispatchTouchEvent和onInterceptTouchEvent的ACTION_DOWM决定该事件流程的走向(由dispatchTouchEvent决定是否分发给onInterceptTouchEvent,再通过onInterceptTouchEvent决定是否拦截)。这里只是决定事件的一个流程走向,至于某种状态(三种状态的一种)按照这个流程走向是否执行完所有流程,请看下面一条。
4.如果事件处理方法返回true,表示该状态(三种状态的一种)下的事件已经被消化了,该状态下的事件不再传递,但是并不影响其他状态(三种状态的一种)的事件处理。否则会继续向下传递事件
欢迎指出不足,没事下留言,你的支持,是我写下去的动力
最近小明遇到问题老是问我,其中有一个问题是这样的:
小明:在ScrollView嵌套ListView,ListView无发滑动
一看就知道他不懂安卓事件处理机制,然后我耐心帮他讲解,最后虽然他懂了,但是我还是觉得有必要总结下安卓事件处理机制。
一.什么是事件
事件就是对触摸屏幕的操作,比如触摸事件,单机事件,滑动事件等。
用户对触摸屏幕的所有操作,都是先按下去,最后弹起来,按下去的时候可以进行一段移动,再弹起来,也就是说说有基本事件都包括这三种事件状态:
按下(ACTION_DOWM)
移动(ACTION_MOVE)
弹起(ACTION_UP)
安卓为响应这些事件,提供一个类MotionEvent,其中有这样一句话:
Motion events are always delivered to views as a consistent stream of events. What constitutes a consistent stream varies depending on the type of device. For touch events, consistency implies that pointers go down one at a time, move around as a group and
then go up one at a time or are canceled.
翻译:请求事件总是依照一个始终如一的事件流传递给视图。什么是一个始终如一的流变化取决于设备的类型。对触摸事件,一致性意味着指针走一次,作为一个整体移动,然后向上一次或被取消。
也就是说事件从点击的子视图(View)开始,向上传递事件给父视图(ViewGroup),一直传递到传递到Activity。
而安卓的事件处理流程则是由Activity的dispatchTouchEvent,再到ViewGroup的dispatchTouchEvent,再到Viewgroup的onInterceptTouchEvent,一直传递到点击的子视图View
二.view的事件分发以及viewgroup的事件分发和拦截
通过查看view的源码,发现view只有dispatchTouchEvent,OnTouchEvent
通过查看Viewgroup的源码,发现viewgroup不仅有dispatchTouchEvent,OnTouchEvent,还有onInterceptTouchEvent
dispatchTouchEvent:方法用于事件的分发,Android中的所有事件都必须经过此方法的分发,然后决定是自身消费当前事件还是继续向下分发给 视图处理。返回true表示不在继续分发,事件被消费了。返回false则事件继续分发,如果是viewgroup则分发给onInterceptTouchEvent进行判断是否拦截
OnTouchEvent:方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。
onInterceptTouchEvent:是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的
三.从一个案例让你了解事件执行流程
案例1:view的事件分发
1.自定义类JesseButton继承Button
温馨提示:这里鼠标要稍微滑动下,才能响应事件的移动状态(即才会有ACTION_MOVE)
由此可以看出,View事件执行流程是:
(Activity)dispatchTouchEvent-->(Button)dispatchTouchEvent-->(Button)onTouch-->(Button)onTouchEvent
案例2:viewgroup的事件分发和事件拦截
在原来基础上新增一个类JesseLinearLayout
由此可以看出,Viewgroup事件执行流程是:
(Activity)dispatchTouchEvent-->(LinearLayout)diapatchTouchEvent-->(LinearLayout)onInterceptTouchEvent-->(Button)dispatchTouchEvent-->(Button)onTouch-->(Button)onTouchEvent
四.一张图让你了解事件处理流程的走向
默认执行流程是
(Activity)dispatchTouchEvent(ACTION_DOWM返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_DOWM返回false)-->(LinearLayout)onInterceptTouchEvent(ACTION_DOWM返回false)-->(Button)dispatchTouchEvent(返回false)-->(Button)onTouch(返回false)-->(Button)onTouchEvent
假如在(LinearLayout)diapatchTouchEvent的ACTION_DOWM返回true,三种状态执行的事件是:
ACTION_DOWM状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_DOWM返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_DOWM返回false)
ACTION_MOVE状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_MOVE返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_MOVE返回false)-->(LinearLayout)onInterceptTouchEvent
ACTION_UP状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_UP返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_UP返回false)-->(LinearLayout)onInterceptTouchEvent
如果我们不想ACTION_UP状态的(LinearLayout)onInterceptTouchEvent执行,只需要(LinearLayout)diapatchTouchEvent(ACTION_UP返回true)即:
ACTION_UP状态执行的事件是:(Activity)dispatchTouchEvent(ACTION_UP返回false)-->(LinearLayout)diapatchTouchEvent(ACTION_UP返回true)
五.解释和总结:
继续重复-----事件包括最基本的三种状态:按下(ACTION_DOWM),移动(ACTION_MOVE),弹起(ACTION_UP)
1.我们单击view,这时候事件由view通过MotionEvent向上传递事件,先传递给ViewGroup再通过MotionEvent向上传递事件,直到Activity
2.事件默认处理流程则相反,由Activity的dispatchTouchEvent向下传递事件,先传递给ViewGroup的dispatchTouchEvent,再传递给ViewGroup的onInterceptTouchEvent,最后传递到View的dispatchTouchEvent
3.由dispatchTouchEvent和onInterceptTouchEvent的ACTION_DOWM决定该事件流程的走向(由dispatchTouchEvent决定是否分发给onInterceptTouchEvent,再通过onInterceptTouchEvent决定是否拦截)。这里只是决定事件的一个流程走向,至于某种状态(三种状态的一种)按照这个流程走向是否执行完所有流程,请看下面一条。
4.如果事件处理方法返回true,表示该状态(三种状态的一种)下的事件已经被消化了,该状态下的事件不再传递,但是并不影响其他状态(三种状态的一种)的事件处理。否则会继续向下传递事件
欢迎指出不足,没事下留言,你的支持,是我写下去的动力
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories