更新
This commit is contained in:
147
lib/pages/sleep_report/chart/FatigueCircleIndicator.dart
Normal file
147
lib/pages/sleep_report/chart/FatigueCircleIndicator.dart
Normal file
@@ -0,0 +1,147 @@
|
||||
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: percent > 60
|
||||
? themeController.currentColor.sc9
|
||||
: themeController.currentColor.sc3,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4.rpx),
|
||||
Text(
|
||||
explain,
|
||||
style: TextStyle(
|
||||
fontSize: AppConstants().normal_text_fontSize,
|
||||
color: percent > 60
|
||||
? themeController.currentColor.sc9
|
||||
: themeController.currentColor.sc3,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user