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

Flutter中如何让带圆角StrokeCap的圆弧渐变完全覆盖末端?

解决Flutter中SweepGradient结合StrokeCap.round末端颜色缺失问题

问题原因

当为圆弧设置StrokeCap.round时,圆弧的两端会各延伸出一个半径等于strokeWidth/2的半圆帽。原代码中SweepGradient的endAngle刚好等于圆弧的终点角度(pi*2),导致末端帽的区域超出了渐变范围,无法显示绿色。

解决方案

通过扩展SweepGradient的endAngle范围,让渐变覆盖末端帽的区域,同时明确色标位置保证颜色过渡准确。具体步骤:

  • 计算圆弧半径,根据strokeWidth得出末端帽对应的圆心角偏移量
  • 将渐变的endAngle增加该偏移量,确保覆盖帽的区域
  • 设置colorStops明确颜色过渡节点,避免渐变偏移

修改后的完整代码

import 'dart:math';

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Custom Gauge Example')),
        body: const Center(
          child: CustomPaint(
            size: Size(200, 100),
            painter: GaugePainter(),
          ),
        ),
      ),
    );
  }
}

class GaugePainter extends CustomPainter {
  const GaugePainter();

  @override
  void paint(Canvas canvas, Size size) {
    const strokeWidth = 16.0;

    final rect = Rect.fromLTWH(
      strokeWidth / 2,
      strokeWidth / 2,
      size.width - strokeWidth,
      size.height * 2 - strokeWidth * 2,
    );
    // 计算圆弧的半径
    final radius = (size.width - strokeWidth) / 2;
    // 计算StrokeCap.round对应的额外圆心角偏移(帽的长度对应圆心角=弧长/半径)
    final capAngle = (strokeWidth / 2) / radius;

    final gradient = SweepGradient(
      startAngle: pi,
      // 扩展渐变结束角度,覆盖末端帽区域
      endAngle: pi * 2 + capAngle,
      colors: const [Colors.red, Colors.yellow, Colors.green],
      // 明确色标位置,保证颜色过渡准确
      colorStops: const [0.0, 0.5, 1.0],
    );

    final gradientShader = gradient.createShader(rect);

    canvas.drawArc(
      rect,
      -pi,
      pi,
      false,
      Paint()
        ..shader = gradientShader
        ..style = PaintingStyle.stroke
        ..strokeCap = StrokeCap.round
        ..strokeWidth = strokeWidth,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

补充说明

  • 计算capAngle是为了精准匹配帽的长度,避免过度扩展渐变范围导致颜色失真
  • 如果不需要极致精准,也可以直接给endAngle添加一个固定小值(如pi*2 + 0.1),同样能解决问题,但精准计算适配不同尺寸和strokeWidth的场景更可靠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:13:18