您的位置:首页 > 移动开发 > Android开发

android 事件分发机制实验解析,从实验上一步一步带大家理解分发机制

2016-12-27 11:37 316 查看
前言:事件分发是各位Android开发人员必学的课程,我现在带领大家一起一步一步的打印运行,从最基础上理解disapatchTouchEvent、OnInterceptTouchEventOnTouchEvent执行过程。

事件分发机制总结

事件分发里,View和ViewGroup的事件分发机制不一样。

这里先讲View的分发,View有两个重要的方法,事件分发dispatchTouchEvent和事件处理onTouchEvent

disapatchTouchEvent这里有两个返回值,如果返回true,代表着事件被消费,不传递给自身的onTouchEvent。如果返回false,那个这个事件就传给自己的父层,如果父层是Activity就传给ActivityonTouchEvent消费

onTouchEevnt是事件处理的方法,方法带了动作参数MotionEvent,这里面可以获取用户手指在屏幕上各种操作,有Action_Down、Action_Up、Action_move等动作,onTouchEventdispatchTiouchEvent一样具有boolean返回值,返回true代表着自己消费,返回false代表着自身不消费,交给自己的父层控件消费

 

ViewGrou的事件分发机制里同时具备有上面的两个方法,而且还多了一个事件拦截的方法。

ViewGroup的事件分发方法dispatchTouchEvent返回值不管返回true还是false都不分发事件,并且结束当前事件。如果返回的是super.dispatchTouchEvent就会调用事件拦截方法OnInterceptTouchEvent。这个方法也是boolean返回值,返回true代表着事件被拦截,不分分发给子层控件onTouchEvent处理,返回false为不拦截此事件,交给子层控件OnTouchEvent处理,如果事件源是从子控件来的,那么父层的OnTouchEvent不会执行

界面预览



 

实验一:



下面一个LinearLayout ,上面一个Button,在没有给这两个控件设置任何事件和修改任何代码的情况下,只在这两个控件的事件分发相关方法下打印一下,情况如下

Action_Dwon  --> Action_up,手指按下与抬起

 


可以看到执行了这两个控件都执行了两次,为什么会执行两次呢?

因为当用户的手指按在Button上,这会执行一次Action_Down。这就一次了,当手指抬起来后会执行Action_UP,加起来两次了。所以就看到事件分发了两次。

而且你会看到事件从父层控件开始往上冒泡传递事件

 

下面来看看手指Action_Dwon --> Action_Move  --> Action_up是什么效果

 


可以看到,效果是一样的,只是LinearLatoyt和Button各自多了一次分发事件

 

为什么MyLayout的OnTounchEvent没有响应执行?

实验开始

1. 在MyLayout布局文件中加上android:clickable="true"

2. 当我点击Button按钮周边的空白处,MyLayout的OnTounchEvent的事件响应了。我们来看看打印的效果。Action_Down
 --> Action_Up


 


可以看到空白处的MyLayout当手指点击还是会执行的,跟点击Button没什么差别。但是为什么OnIntercepTouchEvent()只执行了Action_Down事件?

仔细的想了一下:我发现是因为点击的是MyLayout这个父级容器,已经没有事件让父级容器向上传递了,但是为什么只执行一次?我想是因为手指触发的是MyLayout的事件,不需要传递事件给其他子View,所以事件拦截方法不需要再次拦截

3.如果不在在MyLayout布局文件中加上android:clickable="true"的话

 


可以看到,事件只执行了Action_Down

 

实验二:只在Activity上放置MyLayout


在MyLayout分别在事件分发、事件拦截、和事件响应三大方法中返回不同属性会发生什么?

1. 首先在dispatchTouchEvent返回true,点击BUtton时

a) 


b) Button的点击事件没有分发出去,Down和Up方法全部被MyLayout的
dispatchTouchEvent消费掉

2. dispatchTouchEvent返回false,点击BUtton时

a) 


b) 这里看到只执行了一次Action_Down方法

 

3. 在intercepTouchEvent返回true,点击Button时

a) 


b) 事件被拦截了,没有向下传递了

 

4.  在intercepTouchEvent返回flase,点击Button时

a) 


b) 事件没有拦截,继续向下传递,跟返回supe.intercepTouchEvent()一下效果,这里可以得出:默认intercepTouchEvent返回是false,事件传递给子控件

 

5. MyLayout的onTouchEvent没有触发,所以不在MyLayout里的事件响应方法里面返回返回值做实验,因为触摸的是Button的事件,所以
MyLayout的onTouchEvent不会触发

 
[b]实验三:只在Activity上放置MyView
[/b]
在Button里分别在事件分发、和事件响应三大方法中返回不同属性会发生什么?

1.  在Button的dispatchTouchEvent返回true,点击BUtton时

a) 


b) 可以看到在Button里的事件分发方法了返回true,Button的点击事件被消费掉,没有向下传递给onTouchEnent

2.  在Button的dispatchTouchEvent返回false,点击BUtton时

a) 


b) 可以看到在Button的事件分发里面返回false,Button的onTouchEvent没有消费,而是交给了MyLayout的onTouchEvent消费

 

3. 3. 在Button的
onTouchEvent返回true,点击BUtton时


a) 


b) 可以看到在Button里的onTouchEvent返回true,Button的点击事件继续执行,没有收到影响,自己消费掉事件

 

4. 4. 在Button的
onTouchEvent返回false,点击BUtton时


a) 


b) 可以看到Button里的onTouchEvent返回false,Button的点击事件只响应了Action_Down事件,自己不再进行消费,然后交给了父级MyLayout的onTouchEvent消费

 

 

 

View事件分发机制,简短总结

dispatchTouchEvent返回true,自身消费。分发结束,不传递给自身的onTouchEvent处理

dispatchTouchEvent返回false,自身不消费,不会交给自身的onTouchEvent处理,交给父层

的onTouchEvent处理

onTouchEvent返回true,自身消费

onTouchEvent返回false,自身不消费,交给父层onTouchEvent消费

 

ViewGroup事件分发机制,简短总结

dispatchTouchEvent返回true,自身消费。分发结束,不传递给自身的onTouchEvent处理

dispatchTouchEvent返回false,自身消费。分发结束,不传递给自身的onTouchEvent处理

dispatchTouchEvent返回super.dispatchTouchEvent,会调用事件拦截方法onIntercepTouchEvent

 

onIntercepTouchEvent返回true,拦截此事件,事件结束

onIntercepTouchEvent返回false,不拦截此事件,事件传递给子类

 

如果事件是从子层控件来的,那么onTouchEvent将不会执行

如果事件是从自身控件来的,那么

onTouchEvent返回true,自身消费

onTouchEvent返回false,自身不消费,传递给父层控件onTouchEvent消费
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐