코드
<script>
import 'dart:ui';
import 'package:flutter/material.dart';
import 'dart:math';
class DonutChart1Page extends StatefulWidget {
@override
State<DonutChart1Page> createState() => _DonutChart1PageState();
}
class _DonutChart1PageState extends State<DonutChart1Page> with TickerProviderStateMixin {
double percentage = 0.0;
double newPercentage = 0.0;
late AnimationController percentageAnimationController;
@override
void initState() {
super.initState();
percentageAnimationController = AnimationController(
vsync: this,
duration: new Duration(milliseconds: 2000)
)
..addListener((){
setState(() {
percentage=lerpDouble(percentage,newPercentage,percentageAnimationController.value)!;
});
});
setState(() {
percentage = newPercentage;
newPercentage=0.8;
percentageAnimationController.forward();
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
bottom: false,
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios_new,
color: Colors.black, size: 18),
onPressed: () {
Navigator.pop(context);
},
),
title: Text('가운데 글자 도넛'),
centerTitle: true,
),
body: Center(
child:PercentDonut(percent: percentage, color: Colors.lightBlue),
),
),
);
}
}
class PercentDonut extends StatelessWidget {
const PercentDonut({Key? key, required this.percent, required this.color})
: super(key: key);
final percent;
final color;
@override
Widget build(BuildContext context) {
return Container(
width: 310,
height: 310,
child: CustomPaint(
painter: PercentDonutPaint(
percentage: percent,
activeColor: color,
),
),
);
}
}
class PercentDonutPaint extends CustomPainter {
double percentage;
double textScaleFactor = 1.0;
Color activeColor;
PercentDonutPaint({required this.percentage, required this.activeColor});
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Color(0xfff3f3f3)
..strokeWidth = 15.0
..style =
PaintingStyle.stroke
..strokeCap =
StrokeCap.round;
double radius = min(
size.width / 2 - paint.strokeWidth / 2,
size.height / 2 -
paint.strokeWidth / 2);
Offset center =
Offset(size.width / 2, size.height / 2);
canvas.drawCircle(center, radius, paint);
double arcAngle = 2 * pi * percentage;
paint.color = activeColor;
canvas.drawArc(Rect.fromCircle(center: center, radius: radius),-pi / 2,
arcAngle, false, paint);
drawText(canvas, size, "${(percentage*100).round()} / 100");
}
void drawText(Canvas canvas, Size size, String text) {
double fontSize = getFontSize(size, text);
TextSpan sp = TextSpan(
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: Colors.black),
text: text);
TextPainter tp = TextPainter(text: sp, textDirection: TextDirection.ltr);
tp.layout();
double dx = size.width / 2 - tp.width / 2;
double dy = size.height / 2 - tp.height / 2;
Offset offset = Offset(dx, dy);
tp.paint(canvas, offset);
}
double getFontSize(Size size, String text) {
return size.width / text.length * textScaleFactor;
}
@override
bool shouldRepaint(PercentDonutPaint oldDelegate) {
return true;
}
}
</script>
결과