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

如何让Container仅填充CustomPainter绘制的电池形状区域?

实现自定义电池形状的填充效果

要让Container的颜色仅填充你绘制的电池形状,核心是用**自定义路径裁剪(ClipPath)**替代原有的ClipRRect,具体修改方案如下:

1. 复用电池路径

先把电池形状的路径单独提取出来,方便裁剪和描边逻辑复用:

Path _getBatteryPath(Size size) {
  var path = Path();
  // 绘制电池主体区域
  path.lineTo(size.width * 0.75, 0);
  path.lineTo(size.width * 0.75, size.height * 0.25);
  path.lineTo(size.width * 0.75, size.height);
  path.lineTo(0, size.height);
  path.lineTo(0, 0);
  path.close(); // 闭合主体路径,确保裁剪区域完整
  // 绘制电池顶部突出部分
  path.moveTo(size.width * 0.75, size.height * 0.25);
  path.lineTo(size.width * 0.80, size.height * 0.25);
  path.lineTo(size.width * 0.80, size.height * 0.75);
  path.lineTo(size.width * 0.75, size.height * 0.75);
  path.close(); // 闭合顶部路径
  return path;
}

2. 更新BatteryPainter

修改自定义画笔,复用上面的路径绘制电池边框:

class BatteryPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 4.0;
    var batteryPath = _getBatteryPath(size);
    canvas.drawPath(batteryPath, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

3. 用ClipPath实现形状填充

将原有的ClipRRect替换为ClipPath,通过自定义裁剪器把Container裁剪成电池形状,再叠加画笔绘制边框:

return ClipPath(
  clipper: _BatteryClipper(),
  child: Container(
    width: 100,
    height: 50,
    color: Colors.red, // 电池填充色
    child: CustomPaint(
      painter: BatteryPainter(),
    ),
  ),
);

// 自定义裁剪器类
class _BatteryClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    return _getBatteryPath(size);
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

效果说明

  • ClipPath会严格按照电池路径裁剪Container,让红色仅填充电池的轮廓范围
  • CustomPainter负责绘制黑色边框,最终呈现完整的满电电池视觉效果

电池形状

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 12:48:30