Android与iOS虽然差异很多,但也有共通之处,这次来看看事件分发机制方面,各有何所长吧。
Android事件分发机制
Android中所有事件的传递都是自上而下,然后自下而上的一个传递过程,直到事件被消费,结束掉。
基础认知
1. Android事件构成
在Android中,事件主要包括点按、长按、拖拽、滑动等,点按又包括单击和双击,另外还包括单指操作和多指操作。所有这些都构成了Android中得事件响应。
总的来说,所有的事件都由如下部分作为基础:
| 事件类型 | 具体动作 |
|---|---|
| MotionEvent.ACTION_DOWN | 按下View(所有事件的开始) |
| MotionEvent.ACTION_UP | 抬起View(与DOWN对应) |
| MotionEvent.ACTION_MOVE | 滑动View |
| MotionEvent.ACTION_CANCEL | 结束事件(非人为原因) |
2. 事件列
从手指接触屏幕 至 手指离开屏幕,这个过程产生的一系列事件。
一般情况下,事件列都是以DOWN事件开始、 UP事件结束,中间有无数的MOVE事件,如下图:
View & 处理的整个过程。
即 事件传递的过程 = 分发过程。
4. 事件在哪些对象之间进行传递?
Android的UI界面由:Activity、ViewGroup、View 及其派生类组成
类型简介
5. 事件分发的顺序
即事件传递的顺序:
Activity -> ViewGroup -> View
6. 事件分发过程由哪些方法协作完成?
dispatchTouchEvent()
onInterceptTouchEvent()
onTouchEvent()
事件处理流程图:
子View的onTouchEvent进行事件处理, 如果返回true,则消耗此事件,不会再继续传递;如果返回false,则不处理此事件,把这个事件往上一级的ViewGroup进行传递,由上一级进行处理。
可类比如:上级把任务交给你进行处理,但由于能力不够无法处理,则把任务交给上一级进行处理,如果上一级还处理不了,则继续往上传递处理。
最终事件是否处理,由子View和ViewGroup的onTouchEvent的返回值决定是否会把事件消耗掉。
事件分发机制说明
1. Activity事件分发
当一个点击事件发生时,从Activity的事件分发开始。
方法总结:
2. ViewGroup事件分发
从Activity事件分发机制可知,ViewGroup事件分发机制从dispatchTouchEvent()开始。
Android事件分发总是先传递到ViewGroup、再传递到View。
示意图如下:
核心方法总结:
3. View事件分发
从上面ViewGroup事件分发机制知道,View事件分发机制从dispatchTouchEvent()开始。
每当控件被点击时:
注:onTouch()的执行先于onClick()
核心方法总结:
4. 总结:
工作流程总结
看到这里,恭喜你,Android的事件分发机制已经介绍完成了!
接下来,看看iOS的吧!
iOS事件分发机制
事件介绍
iOS中事件一共有四种类型:
-
触摸事件
-
运动事件
-
远程控制事件
-
按压事件
这里就只讨论最常用的触摸事件。
事件产生
-
发生事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中。
-
UIApplication会从事件队列中取出最前面的事件,并将该事件分发下去处理。通常,先发送事件给应用程序的主窗口(keywindow)。
-
keywindow会在视图层次结构中找到一个最合适的视图来处理事件。
事件传递
事件传递过程
-
UIApplication接收到事件,将事件传递给keyWindow。 -
keyWindow遍历subViews的hitTest:withEvent:方法,找到点击区域内合适的视图来处理事件。 -
UIView的子视图也会遍历其subViews的hitTest:withEvent:方法,以此类推。 -
直到找到点击区域内,且处于最上方的视图,将视图逐步返回给
UIApplication。 -
在查找第一响应者的过程中,已经形成了一个响应者链。
-
应用程序会先调用第一响应者处理事件。
-
如果第一响应者不能处理事件,则调用其
nextResponder方法,一直找响应者链中能处理该事件的对象。 -
最后到
UIApplication后仍然没有能处理该事件的对象,则该事件被废弃。
事件传递示意
响应链
iOS中,只有继承UIResponder的对象才能接受并处理事件。想要处理UIView的触摸事件,必须继承UIView。
App中所有的视图都是按照树状结构,除了根视图外,每个视图都有一个父视图,而每个视图都有0个或者多个子视图。这个树状结构就是事件的响应链。
当触摸事件发生之后,系统会执行事件分发和事件响应两个步骤。
事件分发
在找到最合适的view之后,会调用view的touches方法对事件进行响应,如果没有重写view的touches方法,touches默认的做法是将事件沿着响应者链往上抛,交给下一个响应者对象。也就是说,touches方法默认不处理事件,只是将事件沿着响应者链往上传递。
事件响应
在应用程序中,视图放置都是有一定层次关系的,点击屏幕之后该由下方的哪个view来响应需要有一个判断的方式。响应者链是由一系列可以响应事件的对象(继承于UIResponder)组成的,它决定了响应者对象响应事件的先后顺序关系。
下图展示了UIApplication,UIViewcontroller以及UIView之间的响应关系链:
-
UIView如果view是viewcontroller的根view,那么下一个响应者是viewcontroller,否则是super view。
-
UIViewcontroller如果viewcontroller的view是window的根view,那么下一个响应者是window;如果viewcontroller是另一个viewcontroller模态推出的,那么下一个响应者是另一个viewcontroller;如果viewcontroller的view被add到另一个viewcontroller的根view上,那么下一个响应者是另一个viewcontroller的根view。
-
UIWindowUIWindow的下一个响应者是UIApplication。
-
UIApplication通常UIApplication是响应者链的顶端(如果app delegate也继承了UIResponder,事件还会继续传给app delegate)。
iOS方面的了解的不多,先介绍这些啦~
参考资料:
https://www.jianshu.com/p/38015afcdb58
https://www.jianshu.com/p/905e91f1d0d2
https://www.jianshu.com/p/b0884faae603
https://www.jianshu.com/p/74a2f44840fa
与内容相关联文章:
等等,先别走!「码个蛋」又有活动了!参与活动不但可以培养自己的好习惯,还能拿到「码个蛋」IP系列专属奖品,速度要快...
今日问题:
你觉得Android和iOS 事件分发哪家强?
留言格式:
打卡 x 天,答:xxx。
告诉你一个小技巧:
只需3步,你将不会错过任何一篇文章!