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

如何在Flutter中创建多值环形百分比指示器展示所需热量?

Flutter多值百分比热量统计圆弧组件实现

问题背景

开发Flutter项目时,需要实现一个多值百分比圆弧指示器展示各类热量占比。尝试过多个第三方代码仓库,无法复现Figma设计效果;使用CustomPaint和CustomPainter时,难以绘制不同颜色、对应不同数值的多条圆弧。

解决后的实现方案

通过在CustomPainter中按顺序绘制多条圆弧,每条圆弧对应一个数值占比和颜色,累计起始角度实现分段效果。以下是完整代码:

import 'package:flutter/material.dart';

class MultiArcIndicator extends StatelessWidget {
  final List<ArcSegment> segments;
  final double strokeWidth;
  final Size size;

  const MultiArcIndicator({
    super.key,
    required this.segments,
    this.strokeWidth = 20.0,
    this.size = const Size(200, 200),
  });

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: size,
      painter: _MultiArcPainter(
        segments: segments,
        strokeWidth: strokeWidth,
      ),
    );
  }
}

class ArcSegment {
  final double percentage;
  final Color color;

  ArcSegment({required this.percentage, required this.color});
}

class _MultiArcPainter extends CustomPainter {
  final List<ArcSegment> segments;
  final double strokeWidth;

  _MultiArcPainter({required this.segments, required this.strokeWidth});

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = (size.width / 2) - (strokeWidth / 2);
    const startAngle = -90 * (3.1415926 / 180); // 从顶部起始
    double currentAngle = startAngle;

    final paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round; // 圆弧两端圆角匹配设计

    for (final segment in segments) {
      final sweepAngle = segment.percentage * 2 * 3.1415926;
      paint.color = segment.color;
      canvas.drawArc(
        Rect.fromCircle(center: center, radius: radius),
        currentAngle,
        sweepAngle,
        false,
        paint,
      );
      currentAngle += sweepAngle;
    }
  }

  @override
  bool shouldRepaint(covariant _MultiArcPainter oldDelegate) {
    return oldDelegate.segments != segments || oldDelegate.strokeWidth != strokeWidth;
  }
}

// 使用示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      body: Center(
        child: MultiArcIndicator(
          segments: [
            ArcSegment(percentage: 0.3, color: Colors.red),
            ArcSegment(percentage: 0.25, color: Colors.yellow),
            ArcSegment(percentage: 0.45, color: Colors.green),
          ],
          strokeWidth: 25,
        ),
      ),
    ),
  ));
}

关键说明

  • 用ArcSegment类封装每个圆弧的占比和颜色,便于扩展
  • 从顶部(-90度弧度)开始绘制,依次累加每条圆弧的起始角度,实现分段展示
  • 通过strokeCap: StrokeCap.round实现圆弧两端圆角,贴合常见UI设计风格
  • 支持自定义圆弧宽度和组件尺寸,适配不同布局需求

内容的提问来源于stack exchange,提问作者Vishnu Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:12:42