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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:37:26