如何在Flutter中绘制自定义形状并拖动该形状?

8

目前我可以使用CustomPainter绘制矩形。下面是我的CustomPainter中paint方法内的代码。

for (var rectPoints in rectangles) {
  paint.color = rectPoints.color;
  paint.strokeWidth = rectPoints.strokeWidth;
  if (rectPoints.selected != null && rectPoints.selected == true) {
    paint.color = Colors.black45;
  }
  var rect = Rect.fromLTWH(
      rectPoints.startPoint.dx,
      rectPoints.startPoint.dy,
      rectPoints.endPoint.dx - rectPoints.startPoint.dx,
      rectPoints.endPoint.dy - rectPoints.startPoint.dy);
  canvas.drawRect(rect, paint);
}

var rect = Rect.fromLTWH(startPoint.dx, startPoint.dy,
    endPoint.dx - startPoint.dx, endPoint.dy - startPoint.dy);
canvas.drawRect(rect, paint);

一个矩形是一个自定义对象,具有起点、终点和其他绘制该特定矩形所需的属性。现在我想选择一个矩形并重新定位它。任何帮助将不胜感激。谢谢。

请查看答案:https://dev59.com/Frfna4cB1Zd3GeqPx73-#61470963 - Natesh bhat
2个回答

14

你需要追踪矩形位置的状态,与画布绘制独立。最简单的方法是使用StatefulWidget来实现。你还需要使用GestureDetector来捕获pan事件。然后将手势细节连接到矩形的位置,并调用绘图器重新绘制所有内容。

这是一个演示如何在一个矩形中完成上述操作的简单应用程序。扩展到处理多个矩形应该很简单。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Draggable Custom Painter',
      home: Scaffold(
        body: CustomPainterDraggable(),
      ),
    );
  }
}

class CustomPainterDraggable extends StatefulWidget {
  @override
  _CustomPainterDraggableState createState() => _CustomPainterDraggableState();
}

class _CustomPainterDraggableState extends State<CustomPainterDraggable> {
  var xPos = 0.0;
  var yPos = 0.0;
  final width = 100.0;
  final height = 100.0;
  bool _dragging = false;

  /// Is the point (x, y) inside the rect?
  bool _insideRect(double x, double y) =>
      x >= xPos && x <= xPos + width && y >= yPos && y <= yPos + height;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanStart: (details) => _dragging = _insideRect(
        details.globalPosition.dx,
        details.globalPosition.dy,
      ),
      onPanEnd: (details) {
        _dragging = false;
      },
      onPanUpdate: (details) {
        if (_dragging) {
          setState(() {
            xPos += details.delta.dx;
            yPos += details.delta.dy;
          });
        }
      },
      child: Container(
        color: Colors.white,
        child: CustomPaint(
          painter: RectanglePainter(Rect.fromLTWH(xPos, yPos, width, height)),
          child: Container(),
        ),
      ),
    );
  }
}

class RectanglePainter extends CustomPainter {
  RectanglePainter(this.rect);
  final Rect rect;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawRect(rect, Paint());
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

5
我开发了一个名为touchable的库,目的是为了在你绘制在画布上的每个形状中添加手势回调。你可以绘制你的形状并添加onPanUpdateonTapDown回调以拖动你的形状。

以下是检测圆形触摸和拖动的步骤:

以下是一个小例子,直接从Pub Dev网站中获取的:

将你的CustomPaint小部件包装到CanvasTouchDetector中。它接受一个构建器函数作为参数,该函数期望您的CustomPaint小部件,如下所示。

import 'package:touchable/touchable.dart';


CanvasTouchDetector(
    builder: (context) => 
        CustomPaint(
            painter: MyPainter(context)
        )
)

在CustomPainter类的paint方法中,创建并使用TouchyCanvas对象(使用从CanvasTouchDetector和canvas获得的上下文),来绘制你的形状,并可以在此处提供手势回调(如onPanUpdate,onTapDown)以检测您的拖动事件。

var myCanvas = TouchyCanvas(context,canvas);
myCanvas.drawRect( rect , Paint() , onPanUpdate: (detail){
    //This callback runs when you drag this rectangle. Details of the location can be got from the detail object.
    //Do stuff here. Probably change your state and animate
});

谢谢!我会评估。 - SteAp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接