Flutter 进阶:实现带圆角的 CircularProgressIndicator

在 Flutter 中,我们经常使用 CircularProgressIndicator 来展示加载进度。但是你是否注意到:它的进度端始终是"平头"的(直角)?

这在一些 UI 设计中并不美观,特别是想实现类似 Apple 健身环那样"前端圆清澈"效果时,就需要一个带圆角的圆形进度条。


🛠 方法一:使用 CustomPaint 自绘圆角进度

Flutter 的 Canvas 提供了绘制弧形和给进度端点设置样式的能力,我们只需设置 Paint.strokeCap = StrokeCap.round 就可以让进度端头变成圆角。

→ 实现代码:

dart 复制代码
class RoundedCircularProgressIndicator extends StatelessWidget {
  final double progress;
  final double size;
  final double strokeWidth;
  final Color backgroundColor;
  final Color progressColor;

  const RoundedCircularProgressIndicator({
    super.key,
    required this.progress,
    this.size = 40.0,
    this.strokeWidth = 6.0,
    this.backgroundColor = const Color(0xFFE0E0E0),
    this.progressColor = Colors.blue,
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: size,
      height: size,
      child: CustomPaint(
        painter: _RoundedCircularProgressPainter(
          progress: progress,
          strokeWidth: strokeWidth,
          backgroundColor: backgroundColor,
          progressColor: progressColor,
        ),
      ),
    );
  }
}

class _RoundedCircularProgressPainter extends CustomPainter {
  final double progress;
  final double strokeWidth;
  final Color backgroundColor;
  final Color progressColor;

  _RoundedCircularProgressPainter({
    required this.progress,
    required this.strokeWidth,
    required this.backgroundColor,
    required this.progressColor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final center = size.center(Offset.zero);
    final radius = (size.width - strokeWidth) / 2;
    final rect = Rect.fromCircle(center: center, radius: radius);

    final backgroundPaint = Paint()
      ..color = backgroundColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth;

    final progressPaint = Paint()
      ..color = progressColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round; // 圆角关键

    canvas.drawArc(rect, 0, 2 * pi, false, backgroundPaint);
    canvas.drawArc(rect, -pi / 2, 2 * pi * progress, false, progressPaint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

→ 使用示例:

dart 复制代码
RoundedCircularProgressIndicator(
  progress: 0.75,
  size: 80,
  strokeWidth: 10,
  backgroundColor: Colors.grey.shade300,
  progressColor: Colors.green,
),

效果:圆角端头,进度从顶部开始顺时针绘制,大气现代。


📆 方法二:使用第三方库 percent_indicator

percent_indicator 是非常流行的进度指示器库,支持 circularStrokeCap: CircularStrokeCap.round

安装依赖

yaml 复制代码
dependencies:
  percent_indicator: ^4.2.5

使用示例

dart 复制代码
CircularPercentIndicator(
  radius: 40.0,
  lineWidth: 8.0,
  percent: 0.6,
  circularStrokeCap: CircularStrokeCap.round,
  backgroundColor: Colors.grey.shade300,
  progressColor: Colors.purple,
),

很方便,适合快速开发场景。


❌ Flutter 自带的 CircularProgressIndicator 存在的限制

Flutter 默认的 CircularProgressIndicator 没有揭露 strokeCap 设置,不支持圆角端。

如果你想要实现"前端圆角"效果,当前只能选择:

  1. 自绘
  2. 第三方库

📊 方法对比

方法 是否支持圆角 自定义能力 使用难度 推荐度
CustomPaint 自绘 ✅ 高 中 ⭐⭐⭐⭐
percent_indicator ✅ 中 低 ⭐⭐⭐⭐
CircularProgressIndicator ❌ 低 低 ⭐⭐

✅ 总结

本文介绍了如何在 Flutter 中实现 带圆角的圆形进度条,通过:

  • 自绘 CustomPaint
  • 第三方库 percent_indicator

这些技巧可以使进度 UI 更加精致,满足更复杂的产品设计需求。


🐾 后记

如果你正在开发带上传进度、音频处理、视频模块等场景,圆角进度条会大大提升用户体验。

欢迎点赞、收藏、评论!有任何 Flutter 相关问题也可以留言一起探讨!

相关推荐
传奇开心果编程18 小时前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
m0_7381858221 小时前
Flutter 鸿蒙化实战:media_info 适配 OpenHarmony,媒体信息与缩略图
flutter·华为·harmonyos·鸿蒙·媒体
m0_738185821 天前
Flutter 鸿蒙化实战:just_audio 适配 OpenHarmony,功能强大的播放器
flutter·华为·harmonyos·鸿蒙
传奇开心果编程1 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
律宏阔2 天前
Flutter 列表图片内存优化:CachedNetworkImage 与 ClipRRect 的取舍
前端·flutter
律宏阔2 天前
Dart 3 Record:解决 Future.wait 异构返回值的类型问题
前端·flutter
伯伯熊勞2 天前
GetX 巢狀路由教學:用三層 Navigator 做桌面多欄佈局
flutter
传奇开心果编程2 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
m0_738185822 天前
Flutter 鸿蒙化实战:foundation_fluttify 适配 OpenHarmony,Fluttify 桥接层
flutter·华为·harmonyos·鸿蒙
m0_738185822 天前
Flutter 鸿蒙化实战:http_proxy 适配 OpenHarmony,HTTP 代理
flutter·http·华为·harmonyos·鸿蒙