Android Vs iOS 事件分发知多少?

189 阅读6分钟
原文链接: mp.weixin.qq.com

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事件,如下图:

3. 事件分发的本质 将点击事件(MotionEvent)传递到某个具体的View & 处理的整个过程。

即 事件传递的过程 = 分发过程。

4. 事件在哪些对象之间进行传递?

AndroidUI界面由:ActivityViewGroupView 及其派生类组成

类型简介

    

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遍历subViewshitTest:withEvent: 方法,找到点击区域内合适的视图来处理事件。

  • UIView的子视图也会遍历其subViewshitTest: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 事件分发哪家强?

留言格式:

打卡  天,答:xxx

告诉你一个小技巧:

只需3步,你将不会错过任何一篇文章!