[英]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.