[英]Flutter circular progress indicator - repeatable-Custom painter
我想创造这样的东西:想要实现
我已经做到了:到现在为止
我正在努力在这个圆形进度条的 state 处添加垂直线,就像尾随处的线一样。
import 'dart:math';
import 'package:flutter/material.dart';
class LoaderPaint extends CustomPainter {
final double percentage;
LoaderPaint({
required this.percentage,
});
deg2Rand(double deg) => deg * pi / 180;
@override
void paint(Canvas canvas, Size size) {
final midOffset = Offset(size.width / 2, size.height / 2);
final paint = Paint()
..strokeCap = StrokeCap.round
..color = Colors.white
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.drawLine(
Offset(midOffset.dy, 10),
Offset(midOffset.dy,-10),
paint,
);
canvas.drawArc(
Rect.fromCenter(center: midOffset, width: size.width, height: size.height),
deg2Rand(-90),
deg2Rand(360 * percentage),
false,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
使用此stackoverflow 答案中的公式计算行的末尾 position。 由于我们从 -90 度开始角度,因此我们必须将其从 sweepAngle 中移开。
使用此答案中的公式计算直线末端 position 前后 10 个单位的点,插入圆心和直线末端 position。
用canvas.drawLine
画线
以下是更新后的LoaderPaint
class 与这些更改后的样子:
class LoaderPaint extends CustomPainter {
final double percentage;
const LoaderPaint({
required this.percentage,
});
deg2Rand(double deg) => deg * pi / 180;
@override
void paint(Canvas canvas, Size size) {
final radius = size.width / 2;
final sweepAngle = deg2Rand(360 * percentage);
final theta = deg2Rand(-90) + sweepAngle;
final midOffset = Offset(radius, radius);
final endOffset = Offset(radius + radius * cos(theta), radius + radius * sin(theta));
final midEndDiff = sqrt(pow(endOffset.dx - midOffset.dx, 2) + pow(endOffset.dy - midOffset.dy, 2));
final paint = Paint()
..strokeCap = StrokeCap.round
..color = Colors.white
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.drawLine(
Offset(midOffset.dy, 10),
Offset(midOffset.dy,-10),
paint,
);
canvas.drawArc(
Rect.fromCenter(center: midOffset, width: size.width, height: size.height),
deg2Rand(-90),
sweepAngle,
false,
paint,
);
canvas.drawLine(
Offset(endOffset.dx + (10/midEndDiff) * (endOffset.dx - midOffset.dx), endOffset.dy + (10/midEndDiff) * (endOffset.dy - midOffset.dy)),
Offset(endOffset.dx - (10/midEndDiff) * (endOffset.dx - midOffset.dx), endOffset.dy - (10/midEndDiff) * (endOffset.dy - midOffset.dy)),
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
这个 dartpad显示它工作正常。 您可以轻松更改百分比以查看它在各个角度的工作情况。
您必须记住,这仅在CustomPaint
小部件的宽度和高度完全相同的情况下才有效,但是如果宽度和高度不同,您的没有端盖的示例也会中断。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.