这里有一个最小的代码,它使用CustomPaint
和TweenAnimationBuilder
实现了与您想要的非常接近的东西.
来自DARTPAD的屏幕:
代码:
import 'package:flutter/material.dart';
import 'dart:math';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class BorderPainter extends CustomPainter {
final double currentState;
BorderPainter({required this.currentState});
@override
void paint(Canvas canvas, Size size) {
double strokeWidth = 5;
Rect rect = const Offset(5,5) & Size(size.width - 10, size.height - 10);
var paint = Paint()
..color = Colors.white
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke;
double startAngle = -pi / 2;
double sweepAmount = currentState * pi;
canvas.drawArc(rect, startAngle, sweepAmount, false, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: TweenAnimationBuilder(
tween: Tween(begin: 0.0, end: 2.0),
duration: const Duration(seconds: 10),
builder: (context, value, child) {
return Container(
width: 100,
height: 100,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.orange
),
child: CustomPaint(
painter: BorderPainter(currentState: value),
child: Center(
child: Text(
'${value * 100 ~/ 2.0}%',
),
),
),
);
}
),
);
}
}