带有CustomPaint的Flutter GestureDetector不起作用

问题描述 投票:0回答:1

我正在尝试使用CustomPaint和GestureDetector创建一些自定义小部件。但是,我无法使用GestureDetector与绘制的形状正确交互。如果容器是屏幕的宽度和高度,或者根本没有,我只能检测一种形状的onTap。

请注意,我已经尝试了所有HitTestBehavior类型。

这里是代码,它没有在onTap上检测到任何东西:

class CanvasObject {
  Color color = Colors.green[800];
  double strokeWidth = 10.0;
  PaintingStyle style = PaintingStyle.stroke;
}

class CanvasNodeObject extends CanvasObject {
  double x;
  double y;
  double radius = 20;
  PaintingStyle style = PaintingStyle.fill;
  CanvasNodeObject({@required this.x, @required this.y});
}
class CanvasNodePainter extends CustomPainter {
  CanvasNodeObject node;
  CanvasNodePainter({this.node});

  @override
  void paint(Canvas canvas, Size size) {
    Path path;
    Paint nodePaint = Paint()
      ..color = node.color
      ..style = node.style;

    path = Path();
    path.moveTo(0, 0);
    path.addOval(
        Rect.fromCircle(center: Offset(0, 0), radius: node.radius));
    canvas.drawPath(path, nodePaint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

class TestLineDrawing extends StatefulWidget {
  CanvasNodeObject startNode;
  CanvasNodeObject endNode;
  CanvasLineObject line;
  TestLineDrawing({List<double> x, List<double> y})
      : assert(x.length == 2),
        assert(y.length == 2) {
    startNode = CanvasNodeObject(x: x[0], y: y[0]);
    endNode = CanvasNodeObject(x: x[1], y: y[1]);
    line = CanvasLineObject(x: x, y: y);
  }

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

class _TestLineDrawingState extends State<TestLineDrawing> {
  List<Widget> line() {
    return [
      Positioned(
        top: widget.endNode.x,
        left: widget.endNode.y,
        child:
      GestureDetector(
        behavior: HitTestBehavior.opaque,
        child:
        Container(
          height: widget.endNode.radius,
            width: widget.endNode.radius,
            child: CustomPaint(painter: CanvasNodePainter(node: widget.endNode))),
        onTap: () {
          setState(() {
            Random random = Random();
            widget.endNode.color = Color.fromARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));
            debugPrint("EndNodeOnPress " + widget.endNode.color.toString());
          });
        },
      )),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
      children: line(),
    ));
  }

在屏幕上是:enter image description here

flutter flutter-layout flutter-animation
1个回答
0
投票

我通过以下操作解决了这个问题:

  1. 使用path将所有路径添加到称为Path::addPath的顶级路径中>
  2. 覆盖hitTest并使用Path::contains
  3.   @override
      bool hitTest(Offset position) {
        bool hit = path.contains(position);
        return hit;
      }
    
© www.soinside.com 2019 - 2024. All rights reserved.