GestureDetector 在 InteractiveViewer 内平移

问题描述 投票:0回答:1

我正在寻找一种方法来获得可扩展且可用两根手指平移的 InteractiveViewer。使用

panEnabled: false
参数即可轻松完成此操作。

除此之外,我希望交互式查看器的子级能够单独平移到交互式查看器。我的想法是使用 GestureDetector 的 onPanStart 和 onPanUpdate 功能:

GestureDetector(
      onPanStart: (details) {
        print('Pan start at ${details.localPosition}, global: ${details.globalPosition}');
      },
      onPanUpdate: (details) {
        print('Pan update at ${details.localPosition}, global: ${details.globalPosition}');
      },
      ...
)

执行此操作时,GestureDetector 现在似乎正在“赢得”手指在屏幕上轻敲的权利,并且手势检测器,即使使用两根手指,也是获得平移更新的那个。我希望手势检测器响应单指,InteractiveViewer 响应双指。

删除 onPanStart 和 onPanUpdated 确实可以在交互式查看器上进行缩放和平移。但随后我无法对用于拖动元素的子项进行平移。

这可能吗?

flutter dart
1个回答
0
投票

嗯,这并不简单......人工智能模型都建议重写 InteractiveViewer,直到我找到了

Listener
小部件,我可以在其中计算指针并完全关闭手势,我才想出解决方案当发现多个指针时检测器。

class InteractableChild extends StatefulWidget {
  const InteractableChild({super.key});

  @override
  State<InteractableChild> createState() => _InteractableChildState();
}

class _InteractableChildState extends State<InteractableChild> {
  final Set<int> activePointers = {};
  Offset? tappedPoint;

  // Added this to track if we should accept gestures
  bool get shouldHandleGestures => activePointers.length <= 1;

  @override
  Widget build(BuildContext context) {
    print('activePointers: $activePointers');
    return Listener(
      onPointerDown: (PointerDownEvent event) {
        setState(() {
          activePointers.add(event.pointer);
          // Clear tapped point when we shouldn't handle gestures
          if (!shouldHandleGestures) {
            tappedPoint = null;
          }
        });
      },
      onPointerUp: (PointerUpEvent event) => setState(() => activePointers.remove(event.pointer)),
      onPointerCancel: (PointerCancelEvent event) => setState(() => activePointers.remove(event.pointer)),
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTapDown: shouldHandleGestures
            ? (details) {
                print('Tapped at ${details.localPosition}');
                setState(() => tappedPoint = details.localPosition);
              }
            : null,
        onLongPressStart: shouldHandleGestures ? (s) => print('Long press start') : null,
        onLongPressMoveUpdate: shouldHandleGestures ? (_) => print('Long press move ') : null,
        onPanStart: shouldHandleGestures ? (_) => print('Pan start') : null,
        onPanUpdate: shouldHandleGestures ? (_) => print('Pan update') : null,
        child: SomeWidget(),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.