flutter 手势竞技学习理解

225 阅读1分钟

第一部分 手势组件的基本关系

1 我们一般使用 GestureDetector ,GestureDetector 最终build的是RawGestureDetector

GestureDetector -> RawGestureDetector

2 RawGestureDetector 中的gestures就是我们注册的手势。

3 RawGestureDetector 最终build的是Listener()

4 Listener.createRenderObject 最终返回的是 RenderPointerListener
  一个可以处理手指事件的RenderObject。

5 在Listener的 onPointerDown : _handlePointerDown 会调中将gestures 与 事件关联。
 

第二部分 手势的基本传递

1GestureBinding的 _handlePointerEvent 方法开始,_handlePointerEvent方法里面主要包括两个方法的调用 hitTest 和 dispatchEvent
2 hitTest的作用主要是返回一个HitTestResultHitTestResult里面包含一个`List<HitTestEntry>` 是用于分发和竞争事件的,而每个 `HitTestEntry.target` 都会存储每个控件的 `RenderObject` 。
3 hitTest的实现主要在  RendererBinding.hitTest`GestureBinding.hitTest`根据with的先后顺序,先执行 `RendererBinding.hitTest`,再执行 `GestureBinding.hitTest`.hitTest自下而上的得到了一个 `HitTestResult` 的相应控件列表了,最底下的 Child 在最上面.
4 GestureBinding.dispatchEvent 做事件分发,遍历调用entry.target.handleEvent(),事实上并不是所有的控件的 `RenderObject` 子类都会处理 `handleEvent` ,大部分时候,只有带有 `RenderPointerListener` (RenderObject) / `Listener` (Widget) 的才会处理 `handleEvent` 事件,并且从上述源码可以看出,handleEvent 的执行是不会被拦截打断的。
 从这里就跟第一部分的内容关联上了。

第三部分 _handlePointerDown->addPointer->addAllowedPointer

在addAllowPointer中,虽然不同的recognizer实现不一样,但是都会把自己加入到竞技场。

    void _handlePointerDown(PointerDownEvent event) {
      assert(_recognizers != null);
      for (final GestureRecognizer recognizer in _recognizers!.values) {
        recognizer.addPointer(event);
      }
    }


    void addPointer(PointerDownEvent event) {
      _pointerToKind[event.pointer] = event.kind;
      if (isPointerAllowed(event)) {
        addAllowedPointer(event);
      } else {
        handleNonAllowedPointer(event);
      }
    }

加入竞技场,竞技场在GestureBinding中维护.

GestureBinding.instance.gestureArena.add(event.pointer, this)
    GestureArenaEntry add(int pointer, GestureArenaMember member) {
      //创建pointer对应的竞技场,member就是regcognizder。每个member都会被封窗成GestureAernaEbtry.
      final _GestureArena state = _arenas.putIfAbsent(pointer, () {
        assert(_debugLogDiagnostic(pointer, '★ Opening new gesture arena.'));
        return _GestureArena();
      });
      state.add(member);
      assert(_debugLogDiagnostic(pointer, 'Adding: $member'));
      return GestureArenaEntry._(this, pointer, member);
    }