如何在Flutter中创建带自定义边框描边的百分比指示器
自定义环形进度指示器实现方案
既然percent_indicator包配置不够灵活,直接用Flutter自带的CustomPaint自定义实现是最靠谱的,完全能满足你图中的效果需求。
实现思路
用Stack组件堆叠三层:
- 底层:灰色的环形背景
- 中层:彩色的进度环(根据百分比动态绘制)
- 顶层:中间的文字(包含标题和百分比)
完整代码示例
import 'package:flutter/material.dart'; class CustomCircularProgress extends StatelessWidget { final double progress; // 0-1之间的进度值 final String title; final Color progressColor; final Color bgColor; final double strokeWidth; final double size; const CustomCircularProgress({ super.key, required this.progress, required this.title, this.progressColor = Colors.blue, this.bgColor = Colors.grey, this.strokeWidth = 8.0, this.size = 120.0, }); @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: Stack( alignment: Alignment.center, children: [ // 环形背景 CustomPaint( painter: _CircularPainter( progress: 1.0, color: bgColor, strokeWidth: strokeWidth, ), size: Size(size, size), ), // 进度环 CustomPaint( painter: _CircularPainter( progress: progress, color: progressColor, strokeWidth: strokeWidth, ), size: Size(size, size), ), // 中间文字 Column( mainAxisSize: MainAxisSize.min, children: [ Text( title, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 4), Text( '${(progress * 100).toInt()}%', style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, ), ), ], ), ], ), ); } } class _CircularPainter extends CustomPainter { final double progress; final Color color; final double strokeWidth; _CircularPainter({ required this.progress, required this.color, required this.strokeWidth, }); @override void paint(Canvas canvas, Size size) { final center = Offset(size.width / 2, size.height / 2); final radius = (size.width - strokeWidth) / 2; final paint = Paint() ..color = color ..strokeWidth = strokeWidth ..style = PaintingStyle.stroke ..strokeCap = StrokeCap.round; // 进度环两端圆角,和图中效果一致 // 绘制圆弧,从顶部开始(-90度),顺时针绘制 final arcAngle = 2 * 3.1415926 * progress; canvas.drawArc( Rect.fromCircle(center: center, radius: radius), -3.1415926 / 2, // 起始角度:顶部 arcAngle, false, paint, ); } @override bool shouldRepaint(covariant _CircularPainter oldDelegate) { return progress != oldDelegate.progress || color != oldDelegate.color || strokeWidth != oldDelegate.strokeWidth; } } // 使用示例 class DemoPage extends StatelessWidget { const DemoPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: CustomCircularProgress( progress: 0.75, title: '完成率', progressColor: Colors.green, ), ), ); } }
可自定义的参数
progress:0-1的进度值,控制进度环长度title:中间的标题文字progressColor:进度环颜色bgColor:背景环颜色strokeWidth:环形的宽度size:整个组件的尺寸
你可以根据自己的需求调整这些参数,甚至扩展更多样式(比如文字颜色、字体大小、进度环的端点样式等),完全不受第三方包的限制。
内容的提问来源于stack exchange,提问作者sachintha
相关产品推荐
相关产品推荐

