144 lines
4.1 KiB
Dart
144 lines
4.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:vbvs_app/common/color/appConstants.dart';
|
|
import 'package:vbvs_app/common/util/FitTool.dart';
|
|
import 'package:vbvs_app/common/util/MyUtils.dart';
|
|
|
|
class FatigueCircleIndicator extends StatelessWidget {
|
|
final Map<String, dynamic> data;
|
|
|
|
const FatigueCircleIndicator({super.key, required this.data});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final double screenWidth = MediaQuery.of(context).size.width;
|
|
final double radius = (screenWidth * 0.127).clamp(95.rpx, double.infinity);
|
|
|
|
final double strokeWidth = 14.rpx;
|
|
final double backgroundStrokeWidth = 8.rpx;
|
|
|
|
final String name = data["name"];
|
|
final Color color = data["color"];
|
|
final int percent = data["percent"];
|
|
final String explain = data["explain"];
|
|
final Color bottomColor = data["bottomColor"];
|
|
|
|
return Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
SizedBox(
|
|
width: radius * 2,
|
|
height: radius * 2,
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
// 合并绘制背景与进度
|
|
CustomPaint(
|
|
size: Size(radius * 2, radius * 2),
|
|
painter: _CirclePainter(
|
|
percent: percent,
|
|
color: color,
|
|
bottomColor: bottomColor,
|
|
progressStrokeWidth: strokeWidth,
|
|
backgroundStrokeWidth: backgroundStrokeWidth,
|
|
),
|
|
),
|
|
// 中心文本
|
|
Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
'$percent%',
|
|
style: TextStyle(
|
|
fontSize: AppConstants().normal_text_fontSize,
|
|
color: color,
|
|
),
|
|
),
|
|
SizedBox(height: 4.rpx),
|
|
Text(
|
|
explain,
|
|
style: TextStyle(
|
|
fontSize: AppConstants().normal_text_fontSize,
|
|
color: color,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(height: 40.rpx),
|
|
Text(
|
|
name,
|
|
style: TextStyle(
|
|
fontSize: AppConstants().normal_text_fontSize,
|
|
color: themeController.currentColor.sc3,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class _CirclePainter extends CustomPainter {
|
|
final int percent;
|
|
final Color color;
|
|
final Color bottomColor;
|
|
final double progressStrokeWidth;
|
|
final double backgroundStrokeWidth;
|
|
|
|
_CirclePainter({
|
|
required this.percent,
|
|
required this.color,
|
|
required this.bottomColor,
|
|
required this.progressStrokeWidth,
|
|
required this.backgroundStrokeWidth,
|
|
});
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final center = Offset(size.width / 2, size.height / 2);
|
|
final radius = (size.width - progressStrokeWidth) / 2;
|
|
|
|
// 背景环(底色,细)
|
|
final backgroundPaint = Paint()
|
|
..color = bottomColor
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = backgroundStrokeWidth
|
|
..strokeCap = StrokeCap.round;
|
|
|
|
canvas.drawArc(
|
|
Rect.fromCircle(center: center, radius: radius),
|
|
90 * 3.1415926 / 180,
|
|
2 * 3.1415926,
|
|
false,
|
|
backgroundPaint,
|
|
);
|
|
|
|
// 进度环(进度色,粗)
|
|
final progressPaint = Paint()
|
|
..color = color
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = progressStrokeWidth
|
|
..strokeCap = StrokeCap.butt;
|
|
|
|
final sweepAngle = 2 * 3.1415926 * (percent / 100);
|
|
|
|
canvas.drawArc(
|
|
Rect.fromCircle(center: center, radius: radius),
|
|
90 * 3.1415926 / 180,
|
|
sweepAngle,
|
|
false,
|
|
progressPaint,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(_CirclePainter oldDelegate) {
|
|
return oldDelegate.percent != percent ||
|
|
oldDelegate.color != color ||
|
|
oldDelegate.bottomColor != bottomColor ||
|
|
oldDelegate.progressStrokeWidth != progressStrokeWidth ||
|
|
oldDelegate.backgroundStrokeWidth != backgroundStrokeWidth;
|
|
}
|
|
}
|