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

如何在Flutter中实现图片所示的波浪形背景自定义形状?

在Flutter中实现波浪形渐变背景

你当前用椭圆旋转的方式很难做出自然的波浪效果,推荐用自定义路径裁剪或直接绘制波浪的方法,以下是具体实现方案:

方法一:ClipPath + CustomClipper(裁剪容器为波浪形)

这种方式通过自定义裁剪路径,给容器套上波浪形状,再添加渐变背景,代码易维护,调整灵活。

1. 定义波浪裁剪器

class WaveClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    // 从左上角开始,向下到左侧波浪起始点
    path.lineTo(0, size.height * 0.7);

    // 绘制第一个上凸波浪
    final firstControl = Offset(size.width * 0.25, size.height * 0.5);
    final firstEnd = Offset(size.width * 0.5, size.height * 0.65);
    path.quadraticBezierTo(firstControl.dx, firstControl.dy, firstEnd.dx, firstEnd.dy);

    // 绘制第二个下凸波浪
    final secondControl = Offset(size.width * 0.75, size.height * 0.8);
    final secondEnd = Offset(size.width, size.height * 0.6);
    path.quadraticBezierTo(secondControl.dx, secondControl.dy, secondEnd.dx, secondEnd.dy);

    // 闭合路径:从右下角回到左上角
    path.lineTo(size.width, 0);
    path.close();
    return path;
  }

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

2. 使用裁剪器实现渐变背景

替换你原来的头部渐变代码:

Positioned(
  top: 40,
  left: -100,
  child: Container(
    width: 900,
    height: 330,
    child: ClipPath(
      clipper: WaveClipper(),
      child: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: [Color(0xFFA259FF), Color(0xFF7B46C4)], // 增加渐变层次更贴近原图
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
          ),
        ),
      ),
    ),
  ),
)

方法二:CustomPainter直接绘制渐变波浪

如果需要更精细的控制,可以直接用画笔绘制带渐变的波浪路径,性能更优。

1. 定义波浪绘制器

class WavePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // 创建渐变画笔
    final paint = Paint()
      ..shader = LinearGradient(
        colors: [Color(0xFFA259FF), Color(0xFF7B46C4)],
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
      ).createShader(Rect.fromLTWH(0, 0, size.width, size.height));

    // 绘制波浪路径
    final path = Path();
    path.lineTo(0, size.height * 0.7);
    
    final firstControl = Offset(size.width * 0.25, size.height * 0.5);
    final firstEnd = Offset(size.width * 0.5, size.height * 0.65);
    path.quadraticBezierTo(firstControl.dx, firstControl.dy, firstEnd.dx, firstEnd.dy);

    final secondControl = Offset(size.width * 0.75, size.height * 0.8);
    final secondEnd = Offset(size.width, size.height * 0.6);
    path.quadraticBezierTo(secondControl.dx, secondControl.dy, secondEnd.dx, secondEnd.dy);

    path.lineTo(size.width, 0);
    path.close();

    // 绘制到画布
    canvas.drawPath(path, paint);
  }

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

2. 使用绘制器

Positioned(
  top: 40,
  left: -100,
  child: SizedBox(
    width: 900,
    height: 330,
    child: CustomPaint(
      painter: WavePainter(),
    ),
  ),
)

调整技巧(匹配目标图)

  • 波浪高度:修改size.height的比例值(比如把0.7改成0.8),整体抬高或降低波浪
  • 弯曲程度:调整控制点的坐标(比如把firstControl的y值从0.5改成0.4),让波浪更凸或更平缓
  • 多波浪效果:可以继续添加quadraticBezierTo路径段,实现更多起伏
  • 适配屏幕:用MediaQuery.of(context).size获取屏幕尺寸,动态计算控制点位置,适配不同设备

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:55:04