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

如何在Flutter中绘制如图所示的自定义环形饼图?

Flutter 自定义环形饼图实现示例

现成库满足不了需求的话,直接用CustomPaint自定义绘制是最灵活的方案,以下是适配你需求的示例代码:

1. 自定义环形饼图绘制器

import 'package:flutter/material.dart';

class RingPieChartPainter extends CustomPainter {
  // 分段数据:颜色 + 对应数值
  final List<Map<String, dynamic>> segments;
  // 环形的粗细
  final double strokeWidth;
  // 所有分段的总数值
  late final double totalValue;

  RingPieChartPainter({
    required this.segments,
    this.strokeWidth = 30.0,
  }) {
    totalValue = segments.fold(0.0, (sum, seg) => sum + seg['value']);
  }

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = (size.width / 2) - (strokeWidth / 2);
    final startAngle = -90.0 * (3.1415926 / 180); // 从环形顶部开始绘制

    double currentAngle = startAngle;

    // 逐个绘制环形分段
    for (var seg in segments) {
      final sweepAngle = (seg['value'] / totalValue) * 2 * 3.1415926;
      final paint = Paint()
        ..color = seg['color'] as Color
        ..style = PaintingStyle.stroke
        ..strokeWidth = strokeWidth
        ..strokeCap = StrokeCap.round; // 可选:让分段端点变成圆角

      canvas.drawArc(
        Rect.fromCircle(center: center, radius: radius),
        currentAngle,
        sweepAngle,
        false,
        paint,
      );

      currentAngle += sweepAngle;
    }

    // 绘制中心空白区域的背景(可根据需求修改颜色)
    final centerPaint = Paint()..color = Colors.white;
    canvas.drawCircle(center, radius - strokeWidth, centerPaint);
  }

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

2. 使用自定义饼图的Widget

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

  @override
  Widget build(BuildContext context) {
    // 替换成你的实际数据
    final segments = [
      {'color': Colors.blue, 'value': 30.0},
      {'color': Colors.orange, 'value': 20.0},
      {'color': Colors.green, 'value': 25.0},
      {'color': Colors.red, 'value': 15.0},
      {'color': Colors.purple, 'value': 10.0},
    ];

    return SizedBox(
      width: 300,
      height: 300,
      child: CustomPaint(
        painter: RingPieChartPainter(
          segments: segments,
          strokeWidth: 35.0,
        ),
      ),
    );
  }
}

扩展调整说明

  • 要给分段加标签:在paint方法里计算每个分段的中间角度,用canvas.drawText绘制文本即可
  • 调整strokeCap参数可以切换分段端点的样式(圆角/直角)
  • 修改strokeWidth能控制环形的粗细
  • 中心空白区域的背景颜色可按需修改

内容的提问来源于stack exchange,提问作者Tuan Anh Duong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:10:25