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

Flutter实现发票视图锯齿状背景问题求助

实现发票视图锯齿状背景的几种方案

针对你需要的发票锯齿背景效果,以下是几种可行的实现方式,解决CustomPainter使用不当的问题:

一、正确使用CustomPainter绘制填充式锯齿背景

通过自定义Painter绘制完整的带锯齿的背景路径,适合需要纯色填充的场景:

class ZigzagBackgroundPainter extends CustomPainter {
  final Color bgColor;
  final double zigHeight; // 锯齿高度
  final double zigWidth; // 单个锯齿的宽度

  ZigzagBackgroundPainter({
    required this.bgColor,
    this.zigHeight = 8.0,
    this.zigWidth = 16.0,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = bgColor;
    final path = Path();

    // 绘制顶部直线
    path.moveTo(0, 0);
    path.lineTo(size.width, 0);

    // 从右往左绘制底部锯齿
    double currentX = size.width;
    while (currentX > 0) {
      path.lineTo(currentX, size.height);
      path.lineTo(currentX - zigWidth / 2, size.height - zigHeight);
      path.lineTo(currentX - zigWidth, size.height);
      currentX -= zigWidth;
    }

    // 闭合路径并填充
    path.lineTo(0, size.height);
    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(ZigzagBackgroundPainter oldDelegate) {
    return oldDelegate.bgColor != bgColor ||
        oldDelegate.zigHeight != zigHeight ||
        oldDelegate.zigWidth != zigWidth;
  }
}

使用方式

Container(
  width: double.infinity,
  height: 220, // 发票区域高度
  child: CustomPaint(
    painter: ZigzagBackgroundPainter(bgColor: Colors.white),
    child: Column(
      // 这里放置你的发票内容组件
      children: [/* 发票标题、明细等 */],
    ),
  ),
)

二、用ClipPath实现锯齿裁剪效果

如果需要让背景透过锯齿显示(比如锯齿是透明缺口),使用ClipPath裁剪容器边缘更合适:

class ZigzagClipper extends CustomClipper<Path> {
  final double zigHeight;
  final double zigWidth;

  ZigzagClipper({
    this.zigHeight = 8.0,
    this.zigWidth = 16.0,
  });

  @override
  Path getClip(Size size) {
    final path = Path();
    path.moveTo(0, 0);
    path.lineTo(size.width, 0);

    double currentX = size.width;
    while (currentX > 0) {
      path.lineTo(currentX, size.height);
      path.lineTo(currentX - zigWidth / 2, size.height - zigHeight);
      path.lineTo(currentX - zigWidth, size.height);
      currentX -= zigWidth;
    }

    path.lineTo(0, size.height);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(ZigzagClipper oldClipper) {
    return oldClipper.zigHeight != zigHeight ||
        oldClipper.zigWidth != zigWidth;
  }
}

使用方式

ClipPath(
  clipper: ZigzagClipper(),
  child: Container(
    width: double.infinity,
    height: 220,
    color: Colors.white,
    child: /* 发票内容组件 */,
  ),
)

三、堆叠小部件快速实现锯齿边缘

如果不想写自定义Painter,也可以用Row堆叠三角形小部件模拟锯齿:

// 单个锯齿三角形
class ZigTriangle extends StatelessWidget {
  final double width;
  final double height;
  final Color color;

  const ZigTriangle({
    super.key,
    this.width = 16,
    this.height = 8,
    this.color = Colors.white,
  });

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(width, height),
      painter: _TrianglePainter(color: color),
    );
  }
}

class _TrianglePainter extends CustomPainter {
  final Color color;

  _TrianglePainter({required this.color});

  @override
  void paint(Canvas canvas, Size size) {
    final path = Path();
    path.moveTo(0, 0);
    path.lineTo(size.width, 0);
    path.lineTo(size.width / 2, size.height);
    path.close();
    canvas.drawPath(path, Paint()..color = color);
  }

  @override
  bool shouldRepaint(_TrianglePainter oldDelegate) => oldDelegate.color != color;
}

使用方式

Container(
  width: double.infinity,
  height: 220,
  color: Colors.white,
  child: Stack(
    children: [
      // 发票内容
      Positioned.fill(child: /* 发票组件 */),
      // 底部锯齿条
      Positioned(
        bottom: 0,
        left: 0,
        right: 0,
        height: 8,
        child: Row(
          children: List.generate(
            (MediaQuery.of(context).size.width / 16).ceil(),
            (_) => const ZigTriangle(),
          ),
        ),
      ),
    ],
  ),
)

调整说明

  • 修改zigHeight和zigWidth可以控制锯齿的高低和密度
  • 如果需要顶部锯齿,只需调整Painter/ Clipper中路径的绘制方向(从下往上绘制顶部锯齿)
  • 若锯齿颜色与背景不同,可在Painter中单独设置锯齿部分的画笔颜色

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:46:17