flutter - Flutter 用 3 种多种颜色和值绘制圆形边框
问题描述
如何绘制具有多个值的图表样式圆形边框?还动画圆中的每个值动态扩展填充圆的 100%?
解决方案
动画可以由 TweenAnimationBuilder 处理,它将在构建时播放。为了达到预期的效果,我们必须使用 customPainter。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TweenAnimationBuilder(
duration: const Duration(seconds: 2),
tween: Tween(begin: 0.0, end: 1.0),
curve: Curves.easeOutCubic,
builder: (BuildContext context, dynamic value, Widget child) {
return CustomPaint(
painter: OpenPainter(
totalQuestions: 300,
learned: 75,
notLearned: 75,
range: value),
);
},
),
),
);
}
}
class OpenPainter extends CustomPainter {
final learned;
final notLearned;
final range;
final totalQuestions;
double pi = math.pi;
OpenPainter({this.learned, this.totalQuestions, this.notLearned, this.range});
@override
void paint(Canvas canvas, Size size) {
double strokeWidth = 7;
Rect myRect = const Offset(-50.0, -50.0) & const Size(100.0, 100.0);
var paint1 = Paint()
..color = Colors.red
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
var paint2 = Paint()
..color = Colors.green
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
var paint3 = Paint()
..color = Colors.yellow
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
double firstLineRadianStart = 0;
double _unAnswered = (totalQuestions - notLearned - learned) * range / totalQuestions;
double firstLineRadianEnd = (360 * _unAnswered) * math.pi / 180;
canvas.drawArc(
myRect, firstLineRadianStart, firstLineRadianEnd, false, paint1);
double _learned = (learned) * range / totalQuestions;
double secondLineRadianEnd = getRadians(_learned);
canvas.drawArc(myRect, firstLineRadianEnd, secondLineRadianEnd, false, paint2);
double _notLearned = (notLearned) * range / totalQuestions;
double thirdLineRadianEnd = getRadians(_notLearned);
canvas.drawArc(myRect, firstLineRadianEnd + secondLineRadianEnd, thirdLineRadianEnd, false, paint3);
// drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)
}
double getRadians(double value) {
return (360 * value) * pi / 180;
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
推荐阅读
- python - 在 Telebot @bot.message_handler() 中运行,即使它保存在 if 语句中
- android - React Native 应用程序在前台方面滞后
- python-3.x - 如何在 AWS Elastic Beanstalk 上设置 Ray(分布式编程框架)和 Flask 应用程序?
- python - 无法使用 __str__ 显示数据
- python - 在线程中处理不同的任务
- mysql - MySQL事件每1分钟后不删除数据
- python - Pygame - 不受玩家控制的 RPG 战斗风格动画和运动
- javascript - 使用 Puppeteer 查找以某个单词开头的所有 ID
- javascript - 遵循 github 示例时,google-spreadsheet.js (npm) 不起作用
- node.js - 将点几何添加到 Postgresql