有什么办法在Flutter中绘制虚线弧吗?
目前,我正在使用canvas.drawArc,但我不知道如何获得正确的结果。
canvas.drawArc(
rectangle,
startAngle,
fullArcRadius,
false,
Paint()
..color = Colors.black
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = 2.0,
);
答案 0 :(得分:0)
不幸的是,颤振不能很好地处理破折号。不过有一个插件可以帮助您:path_drawing
使用该方法,只需将虚线包装在dashPath
函数中,即可绘制任何虚线。这听起来很简单,但这意味着您不能使用使事情复杂化的canvas.drawArc
方法。您必须改用canvas.drawPath
并找出如何绘制与该弧相同的路径。
这就是我要这样做的方式(我已经输入了我用来绘制适合画布的项目的代码,您可以根据需要使用或忽略它):
import 'package:flutter/material.dart';
import 'package:path_drawing/path_drawing.dart';
class DashedArc extends CustomPainter {
final Color color;
DashedArc({Color color}) : color = color ?? Colors.white;
@override
void paint(Canvas canvas, Size size) {
// TODO: remove me. This makes it easier to tell
// where the canvas should be
canvas.drawRect(
Offset.zero & size,
Paint()
..color = Colors.black
..style = PaintingStyle.stroke);
var width = 520, height = 520, scale;
// this is a simple Boxfit calculation for the `cover` mode. You could
// use the applyBoxFit function instead, but as it doesn't return a
// centered rect it's almost as much work to use it as to just do it
// manually (unless someone has a better way in which case I'm all ears!)
double rw = size.width / width;
double rh = size.height / height;
double actualWidth, actualHeight, offsetLeft, offsetTop;
if (rw > rh) {
// height is constraining attribute so scale to it
actualWidth = rh * width;
actualHeight = size.height;
offsetTop = 0.0;
offsetLeft = (size.width - actualWidth) / 2.0;
scale = rh;
} else {
// width is constraining attribute so scale to it
actualHeight = rw * height;
actualWidth = size.width;
offsetLeft = 0.0;
offsetTop = (size.height - actualHeight) / 2.0;
scale = rw;
}
canvas.translate(offsetLeft, offsetTop);
canvas.scale(scale);
// parameters from the original drawing (guesstimated a bit using
// preview...)
const double startX = 60;
const double startY = 430; // flutter starts counting from top left
const double dashSize = 5;
const double gapSize = 16;
canvas.drawPath(
dashPath(
Path()
// tell the path where to start
..moveTo(startX, startY)
// the offset tells the arc where to end, the radius is the
// radius of the circle, and largeArc tells it to use the
// big part of the circle rather than the small one.
// The implied parameter `clockwise` means that it starts the arc
// and draw clockwise; setting this to false would result in a large
// arc below!
..arcToPoint(Offset(520 - startX, startY), radius: Radius.circular(260), largeArc: true),
// dash is `dashSize` long followed by a gap `gapSize` long
dashArray: CircularIntervalList<double>([dashSize, gapSize]),
dashOffset: DashOffset.percentage(0.005)),
Paint()
..color = Colors.black
..style = PaintingStyle.stroke
..strokeWidth = dashSize);
}
@override
bool shouldRepaint(DashedArc oldDelegate) {
return oldDelegate.color != this.color;
}
}