Android事件拦截/分发/响应 机制

来源:互联网 发布:less.js下载 编辑:程序博客网 时间:2024/06/06 03:10


由于最近做的一个项目嵌套的比较多就深入研究了一下android的事件分发响应拦截,本人总结的的比较简单粗暴,如果有错误的地方欢迎指正.

先上图,假如我们有下面这个布局



首先要说一下onTouevent onTouchListener dispatchTouchEvent 和onInterceptTouchEvent的返回值如果为true则自己解决,false则交给将要传递给的对象解决

然后我们来剖析一下这个简单布局的事件是怎样响应传递分发拦截的

假设爷爷这个根布局接收到了一个touch事件,

从事件分发开始

爷爷有好事当然首先传给爸爸,也就是我们说的事件分发,爸爸同理把事件分发给了儿子,由于在一个界面也就是一个activity中只有根布局生来就有dispatachTouchEvent即事件是否分发给子布局的权利,当然这个权利是activity给他的,子布局只有重写的的时候即子布局是一个自定义控件才能才能声明dispatachTouchEvent的返回值,我们假设dispatachTouchEvent的返回值都为false,所以事件分发将会一层一层的传递,传递给touch事件所能触碰的范围的最底层的view即儿子,此时儿子的onTouchEeventListener如果返回true则自己处理了就不会传递给自定义布局中的onTouchEvent中了,此时儿子得onClickListener也不会响应了,当然首先得儿子得是个自定义布局,如果返回值为false则会传递给自定义view中的touchEvent处理,touchEvent返回true则自己处理了,返回为false则再次传递给了onCLickListener,当然首先得重写了儿子的setOnClickListener,如果我们在onTouchtListener,,touchEvent都返回了false则如果重写了这些方法那么包括setOnClickListener在内这几个方法都会响应.

然后我们来说一下另一种情况即任何一层的布局只要返回值为true,那么他的子布局将不会响应任何touch事件,我们可以这么理解,爷爷有一包糖,爷爷的dispatachTouchEvent返回值为false,那么这包糖即touch事件传给了爸爸,而此时爸爸二婚了,后妈比较坏,在dispatachTouchEvent中返回了true,即后妈和爸爸这个布局自己偷偷吃了这包糖,即爸爸自己响应了touch事件,而不再向儿子即向下传递,当然此时如果爸爸的dispatachTouchEvent也返回了false此时儿子的dispatachTouchEvent返回值为true或false都无所谓了,因为他自己是最小的布局无法再向下传递了.

再来说一下事件响应:

我们假设dispatachTouchEvent都返回了false,即通过事件分发把touch事件的处理权交给了儿子,儿子此时首先是setOnTouchListener响应,如果反回了true此view自己独立消费了即解决了此次touch事件,如果返回false则交给自定义view中的onTouchEvent处理(我们假设儿子是个自定义view),如果此时onTouchEvent反回了false,这就是告诉爸爸这件事我解决不了,即把事件的处理权有换给了爸爸,当然前提是onInterceptTouchEvent返回的是false,即儿子这个自定义view不拦截事件往上传递,如果儿子的自定义view中的onInterceptTouchEvent方法返回了true即拦截了事件的向上传递,此时不管onTouchEvent返回的是false或true他的父布局都无法响应touch事件,爸爸布局的向上传递的拦截过程同理;

最后来说一下事件拦截,即onInterceptTouchEvent,,,onInterceptTouchEvent只在自定义view中才能实现,onInterceptTouchEvent拦截的是所在view的事件向上传递,即只有在onTouchEvent,setOnTouchListener都返回了false才会有效,onInterceptTouchEvent返回值为true则事件不再向父布局传递,


总结一下:事件分发(dispatachTouchEvent)是从上往下传递的即从根布局到一层一层的子布局,事件响应(setOnTouchListener,onTouchEvent)是从touch的最小控件向父布局一层层的向上传递,事件拦截(onInterceptTouchEvent)拦截的是事件响应,拦截的效果是当view不响应touch事件使其touch无法向上传递,

setOnTouchListener的优先权大于onTouchEvent.


初来乍到,如果有什么错误的地方欢迎指正!



1 0
原创粉丝点击