Android事件分发机制(三)事件分发和消费
2016-07-20 14:34
483 查看
以下是一个例子:
假如有3个布局,Scollview A ,Scollview B,ListView C,B是A的子部局,C是B的子部局。ABC三者都是垂直滑动,那么当我触摸手机向下滑动的时候,滑动的是哪个view呢?
倘若明白了Android事件分发机制,这些就很容易理解了。
以下为部分原理:(经常碰到的方法是“事件拦截”和“事件响应”)
ViewGroup中的三个方法:
事件分发(dispatchTouchEvent(MotionEvent ev))
事件拦截(onInterceptTouchEvent(MotionEvent ev))
事件响应(onTouchEvent(MotionEvent ev))
View中只有两个方法:
事件分发(dispatchTouchEvent(MotionEvent ev))
事件响应(onTouchEvent(MotionEvent ev))
Activity中只有两个方法:
事件分发(dispatchTouchEvent(MotionEvent ev))
事件响应(onTouchEvent(MotionEvent ev))
三个方法的调用流程大致如下:
我们还是举一个例子:
LinearLayout A ,Scollview B,ListView C
B是A的子部局,C是B的子部局
当发生触摸事件,事件的分发次序如下:A->B->C
当分发事件结束,事件开始处理,次序如下:C->B->A
例:
假设A为部门经理,B为项目经理,C为员工。
一旦有事情(默认),A会通知B,然后B通知C。
事件分发完毕后,从C开始执行。C做完了自己的事情,就通知B,然后B通知A。
那么再讨论一种情况,倘若我只想要第一个A获取到点击事件,而B和C不用滑动呢?
A直接可以在事件分发的时候就 不告诉B和C有这个事件的发生。
也就是最终是:A接收,A 分发事件,A处理事件。
那么倘若A不仅仅自己要可以获取到触摸事件,而且还要B可以滚动,但是却不想要C和B造成滑动冲突呢?
这次就可以让B不告诉C事件的发生。
A接收,A 分发事件,A不处理事件;B分发事件,A 处理事件。
最终事件分发次序如下:A->B
事件处理次序如下:B->A
当然还有一种与上述两种完全不同的情况,我们不希望A的触摸事件执行,但是B和C却需要获取到触摸事件。
这次就可以让B在处理事件之后,不告诉A。
最终事件分发次序如下:A->B->C
事件处理次序如下:C->B
总结:
1.dispatchTouchEvent(事件分发)
当dispatchTouchEvent返回true时, 分发出去,接着会调用 onInterceptTouchEvent(事件拦截)
当dispatchTouchEvent返回false时,交给 父控件处理
系统默认的情况下,分发给onInterceptTouchEvent
2.onInterceptTouchEvent(事件拦截)
当onInterceptTouchEvent返回true,由他自己的OnTouchEvent处理
当onInterceptTouchEvent返回false,继续分发
系统默认不拦截
3.onTouchEvent(事件响应)
当onTouchEvent返回true时自己处理
当onTouchEvent返回false,继续传递
系统默认继续传递
demo http://download.csdn.net/detail/q610098308/9581657
假如有3个布局,Scollview A ,Scollview B,ListView C,B是A的子部局,C是B的子部局。ABC三者都是垂直滑动,那么当我触摸手机向下滑动的时候,滑动的是哪个view呢?
倘若明白了Android事件分发机制,这些就很容易理解了。
以下为部分原理:(经常碰到的方法是“事件拦截”和“事件响应”)
ViewGroup中的三个方法:
事件分发(dispatchTouchEvent(MotionEvent ev))
事件拦截(onInterceptTouchEvent(MotionEvent ev))
事件响应(onTouchEvent(MotionEvent ev))
View中只有两个方法:
事件分发(dispatchTouchEvent(MotionEvent ev))
事件响应(onTouchEvent(MotionEvent ev))
Activity中只有两个方法:
事件分发(dispatchTouchEvent(MotionEvent ev))
事件响应(onTouchEvent(MotionEvent ev))
三个方法的调用流程大致如下:
我们还是举一个例子:
LinearLayout A ,Scollview B,ListView C
B是A的子部局,C是B的子部局
当发生触摸事件,事件的分发次序如下:A->B->C
当分发事件结束,事件开始处理,次序如下:C->B->A
例:
假设A为部门经理,B为项目经理,C为员工。
一旦有事情(默认),A会通知B,然后B通知C。
事件分发完毕后,从C开始执行。C做完了自己的事情,就通知B,然后B通知A。
那么再讨论一种情况,倘若我只想要第一个A获取到点击事件,而B和C不用滑动呢?
A直接可以在事件分发的时候就 不告诉B和C有这个事件的发生。
也就是最终是:A接收,A 分发事件,A处理事件。
那么倘若A不仅仅自己要可以获取到触摸事件,而且还要B可以滚动,但是却不想要C和B造成滑动冲突呢?
这次就可以让B不告诉C事件的发生。
A接收,A 分发事件,A不处理事件;B分发事件,A 处理事件。
最终事件分发次序如下:A->B
事件处理次序如下:B->A
当然还有一种与上述两种完全不同的情况,我们不希望A的触摸事件执行,但是B和C却需要获取到触摸事件。
这次就可以让B在处理事件之后,不告诉A。
最终事件分发次序如下:A->B->C
事件处理次序如下:C->B
总结:
1.dispatchTouchEvent(事件分发)
当dispatchTouchEvent返回true时, 分发出去,接着会调用 onInterceptTouchEvent(事件拦截)
当dispatchTouchEvent返回false时,交给 父控件处理
系统默认的情况下,分发给onInterceptTouchEvent
2.onInterceptTouchEvent(事件拦截)
当onInterceptTouchEvent返回true,由他自己的OnTouchEvent处理
当onInterceptTouchEvent返回false,继续分发
系统默认不拦截
3.onTouchEvent(事件响应)
当onTouchEvent返回true时自己处理
当onTouchEvent返回false,继续传递
系统默认继续传递
demo http://download.csdn.net/detail/q610098308/9581657
相关文章推荐
- Android编程:解决异常“android.view.InflateException: Binary XML file line # : Error inflating class”
- 【Android基础】Activity的启动模式(android:launchMode)
- android studio2.0解决办法 Plugin is too old, please update to a more recent version
- Handler详细
- Android VectorDrawable与SVG 实现炫酷动画
- Android断点下载讲解
- 使用Android Studio开发调用.NET Webservice 之初体验
- 自定义GridView的使用(盒子应用)
- 关于android内存管理
- Android实现仿网易首页选项卡动态滑动效果
- android 自定义下拉菜单
- Android应用Design Support Library完全使用实例
- Android资源,国内镜像站点,博客文章等
- android studio 编辑环境里的竖线如何隐藏去掉?
- Android中Strings.xml使用占位符示例
- Android 线程间通信
- Android Databinding 从入门到转行(四)自定义设置通知刷新回调
- Android游戏开发工程师
- Viewpager和PagerSlidingTabStrip的日常玩弄(使用)
- Android 热更新