【问题标题】:Do we have onTapDown and Drag functionality in flutter?Flutter 中是否有 onTapDown 和 Drag 功能?
【发布时间】:2021-10-09 14:02:39
【问题描述】:

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

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

一排有 2 个容器(绿色和橙色)

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

我该如何解决这个问题?

【问题讨论】:

  • 我尝试过使用 GestureDetector 'onTapDown' 并尝试使用具有这些功能的 Listener 'onPointerDown'、'onPointerMove' 仍然无法弄清楚如何执行此操作
  • 不要忘记点赞并将其标记为已解决;)

标签: flutter listener gesturedetector


【解决方案1】:

一种解决方案是用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 并检查以使其仅在矩形更改时发生:

    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;
        }
      },

【讨论】:

  • 您可以将键分配给绿色和橙色容器,并检测触摸点是否在容器中,以使其更加健壮。
  • 嘿,谢谢你的快速回复我试过这个,它在拖动结束后返回“橙色”,但我需要在它达到橙色时立即返回值
  • 那么你需要在dragUpdate方法中计算位置而不是结束,还要添加一个检查它是否仍然是同一个容器而不打印或做任何事情。
  • @Wapazz 当我在拖动更新中更新时它可以工作:) 谢谢
  • 我在答案中添加了使其不会每次都刷新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-21
  • 2020-11-23
  • 2021-09-05
  • 1970-01-01
  • 2011-01-16
  • 2021-11-02
  • 1970-01-01
相关资源
最近更新 更多