Flutter中如何判断用户停止拖动时的位置是否在自身Widget区域内
实现方案
你可以通过记录拖动过程中的最新指针位置,再结合目标Widget的边界坐标做碰撞判断,具体实现步骤如下:
- 第一步:给你的Widget绑定
GlobalKey,用来后续获取它的尺寸和全局位置,同时声明变量存储拖动过程中的最新位置
// 放在State类中定义 final _gestureKey = GlobalKey(); Offset? _lastDragPosition;
- 第二步:给GestureDetector补充
onPanUpdate回调实时更新最新的拖动位置,同时把_gestureKey绑定到GestureDetector上
GestureDetector( key: _gestureKey, onPanDown: (_) => setState(() { // 原有启动动画的逻辑 }), onPanUpdate: (details) { // 实时记录最新的拖动全局坐标 _lastDragPosition = details.globalPosition; }, onPanEnd: (_) => setState(() { // 原有停止动画的逻辑 // 抬起位置边界判断 final renderBox = _gestureKey.currentContext?.findRenderObject() as RenderBox?; if (renderBox == null || _lastDragPosition == null) return; // 将全局坐标转换为Widget的本地坐标 final localPos = renderBox.globalToLocal(_lastDragPosition!); // 判断坐标是否落在Widget的合法区域内 final isInside = localPos.dx >= 0 && localPos.dx <= renderBox.size.width && localPos.dy >= 0 && localPos.dy <= renderBox.size.height; if (isInside) { // 执行你需要的目标回调 yourCallback(); } // 清空存储的位置,避免下次拖动复用旧值 _lastDragPosition = null; }), child: // 你的原有子组件 )
该方案的可行性逻辑:拖动过程中只要手指移动就会触发onPanUpdate,最后一次触发时的坐标就是手指抬起前的实际位置,刚好可以弥补onPanEnd不返回坐标参数的问题。
内容的提问来源于stack exchange,提问作者Haidar
相关产品推荐
相关产品推荐

