Flutter事件处理

一、Flutter事件原理介绍

在移动端,一次完整的时间分为三个阶段:手指按下,手指移动,和手指抬起,而更高级的手势(如点击、双击、拖动等)都是基于这些原始事件。

当手指按下的时候,Flutter会对应用程序执行命中测试(Hit Test),以确定手指与屏幕接触的位置存在哪些组件(widget),手指按下事件(以及该指针的后续事件)然后被分发到由命中测试发现的最内部的组件,然后从那里开始,事件会在组件树向上冒泡,这些事件会从最内部的组件被分发到组件树根路径上的所有组件。只有通过命中测试的组件才能触发事件

Flutter中可以使用Listener来监听原始触摸事件,Listener的构造如下:

 const Listener({
    Key? key,
    this.onPointerDown,//手指按下回调
    this.onPointerMove, //手指移动回调
    this.onPointerUp,//手指抬起回调
    this.onPointerHover,
    this.onPointerCancel,//触摸事件取消回调
    this.onPointerSignal,
    this.behavior = HitTestBehavior.deferToChild,
    Widget? child,
  })

PointerDownEvent、 PointerMoveEvent、 PointerUpEvent 都是PointerEvent的子类,PointerEvent类中包括当前手指的一些信息。

position:它是指针相对于当对于全局坐标的偏移。
localPosition: 它是指针相对于当对于全局坐标的偏移
delta:两次指针移动事件(PointerMoveEvent)的距离。
pressure:按压力度,如果手机屏幕支持压力传感器(如iPhone的3D Touch),此属性会更有意义,如果手机不支持,则始终为1。
orientation:指针移动方向,是一个角度值。

Flutter中封装了GestureDetetor和GestureRecognizer识别和处理手势冲突,具体使用并不难,可以自己去学习。

二、Flutter 事件处理流程

Flutter 事件处理流程主要分为两步,为了聚焦核心流程,我们以用户触摸事件为列:
1.命中测试:当手指按下时,触发PointDownEvent事件,按照深度优先遍历当前渲染树,对每一个渲染对象进行命中测试(hit test),如果命中测试通过,则该渲染对象会被添加到一个HitTestResult列表中。
2.事件分发:命中测试完毕后,会遍历HitTestResult列表,调用每一个渲染对象的事件处理方法(handleEvent)来处理PointerDownEvent事件,改过程为"事件分发"(event dispatch)。随后当手指移动的时,便会分发PointerMoveEvent事件。
3.事件清洗:当手指抬起(PointerUpEvent)或事件取消时(PointerCancelEvent),会先对响应的事件分发,分发完毕后会清空HitTestResult列表。

可以从源码的层面来看整个事件处理流程

// 触发新事件时,flutter 会调用此方法
void _handlePointerEventImmediately(PointerEvent event) {
  HitTestResult? hitTestResult;
  if (event is PointerDownEvent ) {
    hitTestResult = HitTestResult();
    // 发起命中测试
    hitTest(hitTestResult, event.position);
    if (event is PointerDownEvent) {
      _hitTests[event.pointer] = hitTestResult;
    }
  } else if (event is PointerUpEvent || event is PointerCancelEvent) {
    //获取命中测试的结果,然后移除它
    hitTestResult = _hitTests.remove(event.pointer);
  } else if (event.down) { // PointerMoveEvent
    //直接获取命中测试的结果
    hitTestResult = _hitTests[event.pointer];
  }
  // 事件分发
  if (hitTestResult != null) {
    dispatchEvent(event, hitTestResult);
  }
}
三、命中测试

一个对象是否可以响应事件,取决于在其对命中测试过程中是否被添加到了HitTestResult列表,如果没有被添加进去,则后续的时间分发将不会分发给自己。命中测试分两步:
1.renderView是RenderView对应的RenderObject对象,RederObject对象的hitTest方法主要功能是:从该节点出发,按照深度优先的顺序递归遍历子树(渲染树)上的每一个节点并对他进行命中测试。这个过程称为“渲染树命中测试”。
2.渲染树命中测试完毕后,会调用GestureBinding的HitTest方法,该方法主要用于处理手势,我们会在后面介绍。

总结原理

会按照rederObjective树的去深度遍历每个子节点,如果hittest返回true,就是命中测试了,会终止遍历。然后会把从他开始的向上到定点的节点都添加到HitResult里面。然后会遍历HitResult执行他们的handleEvent来处理事件。只有Listener和他的一些子类会执行handleEvent。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容