如何创建堆叠波浪容器

How to create stacked wave containers

我想用这个波浪和相同的曲线来实现这个屏幕,我试图将多个容器堆叠起来以获得这个形状,但我做不到,屏幕的顶部将是图像滑块

这是我用来绘制此屏幕的代码

Scaffold(
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        decoration: BoxDecoration(
          gradient: LinearGradient(
            end: Alignment.centerRight,
            begin: Alignment.centerLeft,
            colors: [
              blueColor,
              lightColor,
            ],
          ),
        ),
        child: Stack(
          alignment: Alignment.topCenter,
          children: [
            Container(
              height: MediaQuery.of(context).size.height * .5,
              decoration: BoxDecoration(),
              child: Stack(
                children: [
                  Container(
                    width: MediaQuery.of(context).size.width,
                    height: MediaQuery.of(context).size.height * .5,
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.only(
                          bottomRight: Radius.circular(100),
                        ),
                        image: DecorationImage(
                            image: AssetImage('assets/images/bg.png'),
                            fit: BoxFit.cover)),
                  ),
                  Positioned(
                    bottom: 0,
                    child: Container(
                      width: MediaQuery.of(context).size.width,
                      height: MediaQuery.of(context).size.height * .08,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.only(
                          bottomRight: Radius.circular(150),
                          topLeft: Radius.circular(150),
                        ),
                        gradient: LinearGradient(
                          end: Alignment.centerRight,
                          begin: Alignment.centerLeft,
                          colors: [
                            blueColor,
                            lightColor,
                          ],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Positioned(
              bottom: 0,
              child: Container(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    end: Alignment.centerRight,
                    begin: Alignment.centerLeft,
                    colors: [
                      blueColor,
                      lightColor,
                    ],
                  ),
                ),
                child: Container(
                  width: MediaQuery.of(context).size.width,
                  height: MediaQuery.of(context).size.height * .5,
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(120),
                      ),
                      color: Colors.white),
                ),
              ),
            ),
          ],
        ),
      ),
    );

但这是我有但不知道要完成的结果

所以有人可以帮助我吗!

你可以用 CustomPainter 来做这个,下面是你的做法和外观。

class StackedWaves extends StatelessWidget {
  const StackedWaves({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(MediaQuery.of(context).size.width,
          MediaQuery.of(context).size.height),
      painter: StackedWavesPainter(),
    );
  }
}

class StackedWavesPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..shader = LinearGradient(colors: [
        Colors.green,
        Colors.lightGreenAccent,
      ]).createShader(Offset.zero & size);
    final double side = 80;
    final double radius = 80;

    final path = Path()
      ..moveTo(0, size.height / 2 + side)
      ..arcToPoint(Offset(side, size.height / 2),
          radius: Radius.circular(radius))
      ..lineTo(size.width - side, size.height / 2)
      ..arcToPoint(Offset(size.width, size.height / 2 - side),
          radius: Radius.circular(radius), clockwise: false)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height)
      ..close();

    canvas.save();
    canvas.drawPath(path, paint);
    canvas.restore();
    
    canvas.save();
    canvas.translate(0, 100);
    canvas.drawPath(path, Paint()..color = Colors.white);
    canvas.restore();
  }

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

当然,如果你愿意,你可以使用变量“side”和“radius”,只要确保它们的差异不超过 20 左右,我见过你是否像那样改变它可能得不到你想要的结果。