如何为CustomPainter中drawPath与drawArc绘制的形状填充颜色?
问题根源
你现在遇到的问题核心在于:代码把整个形状拆分成了多个独立的绘制操作(多次调用drawPath和drawArc),每个操作都是单独的图形元素。当PaintingStyle切换为fill时,只有闭合的图形才会被填充——你单独绘制的线段是开放路径,自然不会被填充,而弧线部分因为是独立的子路径,才会出现局部填充的情况。
解决方案
把所有线段和弧线合并到同一个Path对象中,让整个形状成为一个连续的闭合路径,最后只调用一次canvas.drawPath完成绘制。这样切换到fill模式时,整个闭合区域就能被正确填充。
修改后的完整代码
import 'dart:math' as math; import 'package:flutter/material.dart'; class CustomShapeCard extends CustomPainter { CustomShapeCard({@required this.strokeWidth, @required this.color}); final double strokeWidth; final Color color; @override void paint(Canvas canvas, Size size) { var paint = Paint() ..style = PaintingStyle.fill // 现在切换为fill即可正常填充 ..strokeWidth = strokeWidth ..color = color; // 创建单一Path对象,构建完整形状 var path = Path(); // 起始点 path.moveTo(size.width * 0.1, size.height * 0.2); // 第一条竖线 path.lineTo(size.width * 0.1, size.height * 0.9); // 添加第一个弧线(替代原canvas.drawArc) path.addArc( Rect.fromCenter( center: Offset((size.width * 0.2) - 14, size.height * 0.9), height: 50, width: 50, ), math.pi / 2, math.pi / 2, ); // 从弧线终点继续画线 path.lineTo((size.width * 0.9) - 25, size.height * 0.9 + 25); // 添加第二个弧线 path.addArc( Rect.fromCenter( center: Offset((size.width * 0.9) - 25, size.height * 0.9), height: 50, width: 50, ), math.pi / 2, -math.pi / 2, ); // 继续画线 path.lineTo(size.width * 0.9, size.height * 0.9); path.lineTo(size.width * 0.9, size.height * 0.35); // 添加第三个弧线 path.addArc( Rect.fromCenter( center: Offset((size.width * 0.9) - 25, size.height * 0.35), height: 50, width: 50, ), -math.pi / 2, math.pi / 2, ); // 继续画线 path.lineTo((size.width * 0.9) - 25, (size.height * 0.35) - 25); path.lineTo(size.width * 0.25, (size.height * 0.35) - 25); // 添加第四个弧线 path.addArc( Rect.fromCenter( center: Offset((size.width * 0.25), (size.height * 0.35) - 50), height: 50, width: 50, ), math.pi / 2, math.pi / 3, ); // 回到起始点,闭合路径 path.lineTo(size.width * 0.1, size.height * 0.2); // 绘制完整路径 canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } }
关键修改点说明
- 移除所有零散的
canvas.drawPath和canvas.drawArc调用,将所有线段、弧线整合到同一个Path中; - 用
path.addArc替代canvas.drawArc,让弧线成为主路径的一部分,而非独立图形; - 最后一条线回到起始点,确保路径完全闭合(这是填充生效的必要条件);
- 仅调用一次
canvas.drawPath完成整个形状的绘制。
现在切换PaintingStyle为fill时,整个形状区域就能被正确填充了。
内容的提问来源于stack exchange,提问作者Tushar Patil
相关产品推荐
相关产品推荐

