Android事件分发原理和实例

今天整理资料,发现了好久之前写的一篇文章,关于事件分发的。居然发现全是一点点试的,尴尬并没有涉及到源码的解释。虽然是之前写的,想了想还是贴出来吧,也算是以前自己的一段过程了。至于没有源码,之后我发现一大神写的一篇关于事件分发的源码分析,受益匪浅,也就把地址给出来吧,算是补充了(http://blog.csdn.net/xiaanming/article/details/21696315),羡慕福利呦~~~

 

在我们项目开发中,用到的控件有很多,原生的,自定义的。各种点击、长按、侧滑等事件层出不穷,各种冲突啊等等,这样我们就不得不了解android 的事件分发机制了,涉及到的三个方法 dispatchTouchEvent(MotionEvent ev),onInterceptTouchEvent(MotionEvent ev) , onTouchEvent(MotionEvent ev)。OK  废话不多说了

我们先看结论,结论后面是我的试验过程。。。。大笑


→事件分发:public boolean dispatchTouchEvent(MotionEvent ev)

Touch 事件发生时 Activity  dispatchTouchEvent(MotionEvent ev) 方法会从外向里慢慢传递。事件先传递给最外层 View 的 dispatchTouchEvent(MotionEvent ev) 方法,并由该 View 的 dispatchTouchEvent(MotionEvent ev) 方法对事件进行分发。dispatchTouchEvent 的事件分发逻辑如下:

(1) (MotionEvent ev) 方法返回 true,事件会分发给当前 View 并由 dispatchTouchEvent 方法进行消费,同时事件会停止向下传递;

(2)dispatchTouchEvent(MotionEvent ev) 方法返回 false,事件分发分给父控件/上层控件(Activity)的onTouchEvent 进行消费;

(3)返回系统默认的 super.dispatchTouchEvent(ev),事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。

→事件拦截:public boolean onInterceptTouchEvent(MotionEvent ev) 

在外层 View 的 dispatchTouchEvent(MotionEvent ev) 方法返回系统默认的 super.dispatchTouchEvent(ev) 情况下,事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。onInterceptTouchEvent 的事件拦截逻辑如下:

(1)onInterceptTouchEvent 方法返回 true,则表示将事件进行拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理;

(2)onInterceptTouchEvent 方法返回 false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子 View 的 dispatchTouchEvent 来开始这个事件的分发;

(3)onInterceptTouchEvent 方法返回 super.onInterceptTouchEvent(ev)false的情况,不拦截,继续向下分发事件;

 事件响应:public boolean onTouchEvent(MotionEvent ev)

在 dispatchTouchEvent 返回 super.dispatchTouchEvent(ev) 并且 onInterceptTouchEvent 返回 true 或返回 super.onInterceptTouchEvent(ev) 的情况下 onTouchEvent 会被调用。onTouchEvent 的事件响应逻辑如下:

如果事件传递到当前 View 的 onTouchEvent 方法,而该方法返回了 false,那么这个事件会从当前 View 向上传递,并且都是由上层 View 的 onTouchEvent 来接收,如果传递到上面的 onTouchEvent 也返回 false,这个事件就会消失,而且接收不到下一次事件。

(1)返回了 true 则会接收并消费该事件。

(2)返回 super.onTouchEvent(ev) 默认处理事件的逻辑和返回 false 时相同。


下面我们通过结论和实例的集合来加深认识,写的不全,写了几个感觉都差不多啊~ 道行太浅!

 

Main 的布局文件


1,Activity ,GroupView,View dispatchTouchEvent onInterceptTouchEvent onTouchEvent 都为默认的情况下  点击view 控件

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,默认为false 向下传递→子控件的dispatchTouchEvent 默认→由子控件的onTouchEvent 方法处理→默认上下传递到父控件的onTouchEvent 中处理→默认像上传递到Activity onTouchEvent  中处理,因为默认是false。随后的动作到ActivitydispatchTouchEvent 便不再向下处理)

 

2,当ActivitydispatchTouchEvent  返回true,其设置都为默认的情况时(返回false情况同)

 

(注释:事件传入到activity dispatchTouchEvent,返回值为true/fa;se , 及自己处理Touch事件,不再向下传递)

 

3,当Activity  onTouchEvent为true 其他都为默认的情况下  点击view 控件

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,默认为false 向下传递→子控件的dispatchTouchEvent 默认→由子控件的onTouchEvent 方法处理→默认上下传递到父控件的onTouchEvent 中处理→默认像上传递到Activity onTouchEvent  中处理,返回true→随后的动作到ActivitydispatchTouchEvent 再由onTouchEvent  处理)

 

4,Activity  onTouchEvent为fasle 其他都为默认的情况下 (是不是感觉 返回true 或者false 没有什么差别呢?结果还得从源码中得知!)

 

5,当 ViewGropt(FatherView) dispatchTouchEvent为true 其他都为默认的情况时

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,默认为true 不再向下传递,随后的)

 

6,当 ViewGropt(FatherView) dispatchTouchEvent为false其他都为默认的情况时

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent 返回false不再向下传递,由父控件(上层)的onTouchEvent 接受,随后的事件都不往这个控件里传递,均在上层执行)


7,当 ViewGropt(FatherView) onInterceptTouchEvent为true其他都为默认的情况时

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,返回true→不再向下传递,直接由自己的onTouchEvent 事件处理→默认向上传递,由父控件(Activity )的onTouchEvent事件处理→随后的事件 也均是由Activity dispatchTouchEvent 分发→onTouchEvent事件处理)


8,当ViewGroupFatherView)的onInterceptTouchEvent为false其他都为默认的情况时

 

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,返回false→不拦截,继续向下传递→子控件的dispatchTouchEvent →子控件的onTouchEvent 进行事件处理,→默认向上传递,由父控件(Activity )的onTouchEvent事件处理→随后的事件 也均是由Activity dispatchTouchEvent 分发→onTouchEvent事件处理)


9,当ViewGroup(FatherView)onTouchEvent true时,其他都是默认的情况

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,返回false→不拦截,继续向下传递→子控件的dispatchTouchEvent →子控件的onTouchEvent 进行事件处理,→默认向上传递,由父控件(Activity )的onTouchEvent事件处理→返回True,事件在这里终止→随后的事件 也均是由Activity dispatchTouchEvent 分发→父控件的dispatchTouchEvent →父控件的onTouchEvent事件处理)


10,ViewGroup(FatherView)onTouchEvent false 时,其他都是默认的情况

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,返回false→不拦截,继续向下传递→子控件的dispatchTouchEvent →子控件的onTouchEvent 进行事件处理,→默认向上传递,由父控件(Activity )的onTouchEvent事件处理→返回false,事件在继续向上传递→随后的事件 也均是由Activity dispatchTouchEvent 分发→父控件的onTouchEvent事件处理)


11.当 View(ChildView) dispatchTouchEvent为true 其他都为默认的情况时

 

(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,返回false→不拦截,继续向下传递→子控件的dispatchTouchEvent →返回True,即在本方法中执行Touch事件,不做传递→随后的事件 也均是由Activity dispatchTouchEvent 分发→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,返回false→不拦截,继续向下传递)

 

12.当 View(ChildView) dispatchTouchEvent为false 其他都为默认的情况时


(注释:事件传入到activity dispatchTouchEvent,默认的情况向下继续传递→父控件的dispatchTouchEvent →父控件的onInterceptTouchEvent,返回false→不拦截,继续向下传递→子控件的dispatchTouchEvent →返回false,即不在本控件中做执行,向上传递→随后的事件 也均是由Activity dispatchTouchEvent 分发→Activity onTouchEvent 方法处理)

 

若是哪位师兄弟姐们觉得不错转载了,记得贴上出处哈,搞这些东西真是太麻烦了,花费了不少时间~~~~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值