【问题标题】:How to cancel Gesture if it goes beyond container's bound in Flutter如果手势超出 Flutter 中的容器界限,如何取消手势
【发布时间】:2019-03-04 11:20:06
【问题描述】:

我正在 Flutter 中实现一个绘图应用程序。我指的是this tutorial,但不知何故我被卡住了

简介:如您所见,我有两个容器。一个用于绘图,一个用于“在上方绘制”。但是绘制的点超出了。我希望用户可以在上部容器内绘制。所以我的问题是—— 如果超出特定容器的边界,如何取消手势检测?

代码sn-p:

final GestureDetector paintGesture = GestureDetector(
  onPanUpdate: (DragUpdateDetails details) {
    setState(() {
      RenderBox object = context.findRenderObject();
      Offset _localPosition = object.localToGlobal(details.globalPosition);
      _points = new List.from(_points)..add(_localPosition);
    });
  },
  onPanEnd: (DragEndDetails details) {
      _points.add(null);
  },
  child: sketchArea,
);

final Container sketchArea = Container(
  //margin: EdgeInsets.all(1.0),
  //alignment: Alignment.topLeft,
  color: Colors.white,
  child: new CustomPaint(
    painter: new Signature(points: _points),
    size: Size.infinite,
  ),
);

脚手架:

return new Scaffold(
  body: Container(
    child: Column(
      children: <Widget>[
        Expanded(
          child:  paintGesture,
        ),
        Expanded(
          child: Center(
            child: Container(
              child: Text(
                _selectedInput,
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 40.0,
                ),
              ),
            ),
          ),
        ),
      ],
    ),
  ),
);

【问题讨论】:

  • 你能发布你的完整代码吗?
  • @TruongSinh,我已经发布了我的主要代码 sn-p。 SO建议不要通过发布长帖子来混淆用户,使其清晰易懂。我知道我必须在下面添加一些检查,但不知道如何申请 dart - RenderBox object = context.findRenderObject(); Offset _localPosition = object.localToGlobal(details.globalPosition); _points = new List.from(_points)..add(_localPosition);
  • @TruongSinh 我更新了我的帖子。请检查。

标签: dart flutter gesture


【解决方案1】:

我使用来自this post 的vovohost 解决方案来获取我的Container 的坐标:

扩展:

extension GlobalKeyExtension on GlobalKey {
  Rect get globalPaintBounds {
    final renderObject = 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;
    }
  }
}

用法:

final containerKey = GlobalKey();
Rect get containerRect => containerKey.globalPaintBounds;

Container(
  key: containerKey,
  width: 100,
  height: 50,
)

void printWidgetPosition() {
  print('absolute coordinates on screen: ${containerRect}');
}

获得坐标后,我必须使用此方法在我的Container 范围内返回Offset

Offset _offsetInBox(Offset globalOffset) {
  // Y coordinate
  double nearestY = 0;
  if (globalOffset.dy >= containerRect.top &&
      globalOffset.dy <= containerRect.bottom) {
    nearestY = globalOffset.dy;
  } else {
    if ((containerRect.top - globalOffset.dy).abs() >
        (containerRect.bottom - globalOffset.dy).abs()) {
      nearestY = containerRect.bottom;
    } else {
      nearestY = containerRect.top;
    }
  }

  // X coordinate
  double nearestX = 0;
  if (globalOffset.dx >= containerRect.left &&
      globalOffset.dx <= containerRect.right) {
    nearestX = globalOffset.dx;
  } else {
    if ((containerRect.left - globalOffset.dx).abs() >
        (containerRect.right - globalOffset.dx).abs()) {
      nearestX = containerRect.right;
    } else {
      nearestX = containerRect.left;
    }
  }
  print(
      "Global[${globalOffset.dx}, ${globalOffset.dy}], Found=[$nearestX, $nearestY]");

  return Offset(nearestX, nearestY);
}

在您的 GestureDetector 上,像这样使用它:

final GestureDetector paintGesture = GestureDetector(
  onPanUpdate: (DragUpdateDetails details) {
    setState(() {
      RenderBox renderBox = context.findRenderObject();
      // Use the globalToLocal method if you want the local coordinates, not localToGlobal
      Offset _localPosition = renderBox
                      .globalToLocal(_offsetInBox(details.globalPosition));
      _points = List.from(_points)..add(_localPosition);
    });
  },
  onPanEnd: (DragEndDetails details) {
      _points.add(null);
  },
  child: sketchArea,
);

final Container sketchArea = Container(
  key: containerKey,
  color: Colors.white,
  child: CustomPaint(
    painter: Signature(points: _points),
    size: Size.infinite,
  ),
);

【讨论】:

    猜你喜欢
    • 2020-04-01
    • 2022-01-26
    • 2021-05-06
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多