我正在寻找一种方法来获得可扩展且可用两根手指平移的 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 确实可以在交互式查看器上进行缩放和平移。但随后我无法对用于拖动元素的子项进行平移。
这可能吗?
嗯,这并不简单......人工智能模型都建议重写 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(),
),
);
}
}