首页 > 解决方案 > Flutter 中有 onTapDown 和 Drag 功能吗?

问题描述

我有一个简单的用例,这对于 Flutter 初学者来说是多么的棘手。

我需要为下面解释的场景返回这些值</p>

连续有 2 个容器(绿色和橙色) 在此处输入图像描述

  1. 绿色容器上的 OnTapDown 它应该返回“绿色”(这是直截了当的)
  2. 在没有将手指从屏幕上抬起的情况下,我将手指拖到 Orange 容器上,我需要它来返回“Orange”</li>

我该如何解决这个问题?

标签: flutterlistenergesturedetector

解决方案


一种解决方案可能是用你的布局包装GestureDetector并“猜测”元​​素的位置,然后知道拖动结束的位置。

编辑:感谢@GoodSp33d 评论,添加对目标位置的真实检查以使其更加健壮:

class DragView extends StatefulWidget {
  const DragView({Key? key}) : super(key: key);

  @override
  _DragViewState createState() => _DragViewState();
}

GlobalKey orangeContainerKey = GlobalKey();
GlobalKey greenContainerKey = GlobalKey();

class _DragViewState extends State<DragView> {
  Rect? getGlobalPaintBounds(GlobalKey element) {
    final renderObject = element.currentContext!.findRenderObject();
    var translation = renderObject?.getTransformTo(null).getTranslation();
    if (translation != null && renderObject?.paintBounds != null) {
      return renderObject?.paintBounds
          .shift(Offset(translation.x, translation.y));
    } else {
      return null;
    }
  }

  bool isInRect(double x, double y, Rect? rect) {
    if (rect != null)
      return x >= rect.left &&
          x <= rect.right &&
          y <= rect.bottom &&
          y >= rect.top;
    return false;
  }

  @override
  Widget build(BuildContext context) {
    double _cursorX = 0;
    double _cursorY = 0;

    return GestureDetector(
      onHorizontalDragUpdate: (details) {
        _cursorX = details.globalPosition.dx;
        _cursorY = details.globalPosition.dy;
      },
      onHorizontalDragEnd: (details) {
        if (isInRect(
            _cursorX, _cursorY, getGlobalPaintBounds(orangeContainerKey)))
          print("Orange");
        if (isInRect(
            _cursorX, _cursorY, getGlobalPaintBounds(greenContainerKey)))
          print("Green");
      },
      child: Row(
        children: [
          Expanded(
            child: Container(key: greenContainerKey, color: Colors.green),
          ),
          Expanded(
            child: Container(key: orangeContainerKey, color: Colors.orange),
          ),
        ],
      ),
    );
  }
}

第二次编辑将检测移动到 onDragUpdate 并检查以使其仅在 rect 更改时发生:

    GlobalKey? currentObject;

      onHorizontalDragUpdate: (details) {
        _cursorX = details.globalPosition.dx;
        _cursorY = details.globalPosition.dy;
        if (isInRect(
            _cursorX, _cursorY, getGlobalPaintBounds(orangeContainerKey))) {
          if (currentObject == null || currentObject != orangeContainerKey) {
            print("Orange");
            currentObject = orangeContainerKey;
          }
        }
        if (isInRect(_cursorX, _cursorY,
            getGlobalPaintBounds(greenContainerKey))) if (currentObject ==
                null ||
            currentObject != greenContainerKey) {
          print("Green");
          currentObject = greenContainerKey;
        }
      },


推荐阅读