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
相关产品推荐
相关产品推荐

