Flutter runApp之GestureBinding
在上一篇文章《Flutter runApp到渲染上屏》中,我们介绍了从runApp直到渲染到屏幕上.为了整体流程顺畅因此一些内容没有花过多的文笔描述,所以本章节单独陈述GestureBinding这个mixin对象.
GestureBinding介绍
想去了解一个类最好的方法无外乎去阅读它的注释,我们可以从它的注释中去了解它是为了做什么,做了些什么, 能够做什么.
原文 | 汉译 |
---|---|
A binding for the gesture subsystem. ## Lifecycle of pointer events and the gesture arena ### [PointerDownEvent] When a [PointerDownEvent] is received by the [GestureBinding] (from [dart:ui.PlatformDispatcher.onPointerDataPacket], as interpreted by the [PointerEventConverter]), a [hitTest] is performed to determine which [HitTestTarget] nodes are affected. (Other bindings are expected to implement [hitTest] to defer to [HitTestable] objects. For example, the rendering layer defers to the [RenderView] and the rest of the render object hierarchy.) The affected nodes then are given the event to handle ([dispatchEvent] calls [HitTestTarget.handleEvent] for each affected node). If any have relevant [GestureRecognizer]s, they provide the event to them using [GestureRecognizer.addPointer]. This typically causes the recognizer to register with the [PointerRouter] to receive notifications regarding the pointer in question. Once the hit test and dispatching logic is complete, the event is then passed to the aforementioned [PointerRouter], which passes it to any objects that have registered interest in that event. Finally, the [gestureArena] is closed for the given pointer ([GestureArenaManager.close]), which begins the process of selecting a gesture to win that pointer. ### Other events A pointer that is [PointerEvent.down] may send further events, such as [PointerMoveEvent], [PointerUpEvent], or [PointerCancelEvent]. These are sent to the same [HitTestTarget] nodes as were found when the [PointerDownEvent] was received (even if they have since been disposed; it is the responsibility of those objects to be aware of that possibility). Then, the events are routed to any still-registered entrants in the [PointerRouter]’s table for that pointer. When a [PointerUpEvent] is received, the [GestureArenaManager.sweep] method is invoked to force the gesture arena logic to terminate if necessary. |
手势子系统的绑定。 ## 指针事件和手势竞技场的生命周期 ### [PointerDownEvent] 当 [GestureBinding] 接收到 [PointerDownEvent](来自[dart:ui.PlatformDispatcher.onPointerDataPacket],由[PointerEventConverter]), 执行[hitTest]以确定哪个[HitTestTarget] 节点受到影响。 (其他Bindings预计实现 [hitTest] 以推迟到 [HitTestable] 对象。例如,渲染层遵从 [RenderView] 和渲染对象的其余部分。) 然后给受影响的节点处理事件([dispatchEvent] 调用每个受影响节点的 [HitTestTarget.handleEvent])。如有相关[GestureRecognizer]s,他们使用[GestureRecognizer.addPointer]。这通常会导致识别器向 [PointerRouter] 注册以接收有关有问题的指针。 一旦命中测试和调度逻辑完成,事件就会发生传递给前面提到的 [PointerRouter],它将它传递给任何对象已经注册了对该事件的兴趣。 最后,[gestureArena] 为给定的指针关闭([GestureArenaManager.close]),它开始选择一个赢得该指针的手势。 ### 其他事件 [PointerEvent.down] 的指针可能会发送更多事件,例如[PointerMoveEvent]、[PointerUpEvent] 或 [PointerCancelEvent]。这些是发送到相同的 [HitTestTarget] 节点 [PointerDownEvent] 已收到(即使它们已被处置;它是这些对象有责任意识到这种可能性)。 然后,事件被路由到[PointerRouter] 的指针表。 当接收到 [PointerUpEvent] 时,[GestureArenaManager.sweep] 方法被调用以强制手势竞技场逻辑在必要时终止。 |
methods
了解完GestureBinding大致是做什么的, 我们再了解一下它有哪些方法.
其中initInstances()不知道大家有没有印象, 在BindingBase的构造方法中有调用这个方法, 那自然在初始的时候会调用这个方法.
1 | { |
实际上也就是在开始的时候注册了手势的接收分发.那么手势是如何分发的呢?我们不如看一下_handlePointerDataPacket 的具体实现:
1 | { |
这里又引出来一个_flushPointerEventQueue()的概念,这里会真正的去分发手势事件:
1 | { |
那么, handlePointerEvent() 做了什么呢?
1 | // 断言之类代码已经去掉 |
1 | // 这里会对每一个指针事件进行判断,是否点中widget或者说命中了哪个widget |
这里的代码比较简单, 如果事件是down、signal或者hover之中的任何事件,则会通过hitTest()添加到HitTestResult中,假如是down事件还需要增加到_hitTests结果中.如果是up或者cancel事件,那说明用户取消了当时到滑动事件,我们自然而然需要去除相应的事件.最后去分发手势.
1 | void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) { |
也就是到这里整体到流程就结束了.
总结
从源码开始带着思考去跟踪问题, 也许问题就很容易可以解决了.手势的流程也就是在这一刻注册的,如果你有什么问题? 不妨和我一起讨论
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Weniner!
评论
ValineDisqus