You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中实现百分比环形进度组件的方案咨询

实现Flutter自定义环形百分比进度组件

直接用Flutter自带的CustomPainter就能实现完全自定义的环形进度组件,比第三方包更灵活,能精准匹配你的设计需求,以下是具体实现:

1. 自定义环形进度绘制器

创建RingProgressPainter类,负责绘制背景环、进度环和中间的百分比文字:

import 'dart:math';
import 'package:flutter/material.dart';

class RingProgressPainter extends CustomPainter {
  final double progress; // 0-1之间的进度值
  final Color progressColor;
  final Color backgroundColor;
  final double strokeWidth;
  final TextStyle textStyle;

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

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = min(size.width, size.height) / 2 - strokeWidth / 2;

    // 绘制背景圆环
    final backgroundPaint = Paint()
      ..color = backgroundColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round; // 可选:设置端点为圆角
    canvas.drawCircle(center, radius, backgroundPaint);

    // 绘制进度圆环
    final progressPaint = Paint()
      ..color = progressColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round;
    final arcAngle = 2 * pi * progress;
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -pi / 2, // 从顶部开始绘制
      arcAngle,
      false,
      progressPaint,
    );

    // 绘制中间百分比文字
    final text = '${(progress * 100).toInt()}%';
    final textSpan = TextSpan(text: text, style: textStyle);
    final textPainter = TextPainter(
      text: textSpan,
      textAlign: TextAlign.center,
      textDirection: TextDirection.ltr,
    );
    textPainter.layout(minWidth: 0, maxWidth: size.width);
    final textOffset = Offset(
      center.dx - textPainter.width / 2,
      center.dy - textPainter.height / 2,
    );
    textPainter.paint(canvas, textOffset);
  }

  @override
  bool shouldRepaint(covariant RingProgressPainter oldDelegate) {
    return oldDelegate.progress != progress ||
        oldDelegate.progressColor != progressColor ||
        oldDelegate.backgroundColor != backgroundColor ||
        oldDelegate.strokeWidth != strokeWidth ||
        oldDelegate.textStyle != textStyle;
  }
}

2. 封装成可复用组件

把绘制器包装成RingProgressWidget,方便在项目中调用:

class RingProgressWidget extends StatelessWidget {
  final double progress;
  final Color progressColor;
  final Color backgroundColor;
  final double strokeWidth;
  final TextStyle textStyle;
  final double size;

  const RingProgressWidget({
    super.key,
    required this.progress,
    this.progressColor = Colors.blue,
    this.backgroundColor = Colors.grey.shade200,
    this.strokeWidth = 8.0,
    this.textStyle = const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
    this.size = 120.0,
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: size,
      height: size,
      child: CustomPaint(
        painter: RingProgressPainter(
          progress: progress.clamp(0.0, 1.0), // 确保进度值在0-1之间
          progressColor: progressColor,
          backgroundColor: backgroundColor,
          strokeWidth: strokeWidth,
          textStyle: textStyle,
        ),
      ),
    );
  }
}

3. 使用示例

在页面中直接调用这个组件,比如展示75%的进度:

class ProgressPage extends StatelessWidget {
  const ProgressPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('环形进度示例')),
      body: const Center(
        child: RingProgressWidget(
          progress: 0.75,
          progressColor: Colors.green,
          strokeWidth: 10.0,
          textStyle: TextStyle(fontSize: 28, color: Colors.green),
          size: 150.0,
        ),
      ),
    );
  }
}

自定义说明

  • 调整strokeWidth可改变圆环粗细
  • 修改strokeCap可设置圆环端点为圆角或直角
  • 自定义progressColor和backgroundColor匹配设计风格
  • 调整textStyle可修改百分比文字的大小、颜色和字体

内容的提问来源于stack exchange,提问作者mahdi tabatabaie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:50:23