Flutter 绘制中心有曲线的容器

Bra*_*med 3 user-interface dart flutter

我想用颤动来绘制黑色容器形状。

在此输入图像描述

die*_*per 5

有很多方法可以做到这一点,第一次我以为这是一个剪切,我在一个小部件中思考ClipPath,但现在我看到你的黑色顶部有一个圆形小部件Container

这是一个例子:

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

  Widget _childContainer() {
    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: DecoratedBox(
        decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(
            color: Colors.yellow,
            width: 4,
          ),
          borderRadius: const BorderRadius.all(Radius.circular(20)),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 40),
        child: Container(
          height: 400,
          decoration: const BoxDecoration(
            color: Colors.black,
            borderRadius: BorderRadius.all(Radius.circular(20)),
          ),
          child: Stack(
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  const SizedBox(height: 40),
                  Expanded(child: _childContainer()),
                  Expanded(child: _childContainer()),
                  Expanded(child: _childContainer()),
                ],
              ),
              const Positioned(
                left: 0,
                right: 0,
                top: -50,
                child: CircleAvatar(
                  backgroundColor: Colors.white,
                  radius: 40,
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

更新(使用您更新的设计)

现在您更新了您的帖子,这可以使用 Clippers 来完成,问题是剪辑需要 Shadow,所以我采用了以下代码:https://gist.github.com/coman3/e631fd55cd9cdf9bd4efe8ecfdbb85a7

我在这个例子中使用了:


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(40.0),
          child: ClipShadowPath(
            clipper: _MyClipper(100),
            shadow: const Shadow(
              blurRadius: 15,
              color: Colors.grey,
              offset: Offset(0, 10),
            ),
            child: SizedBox(
              height: 400,
              child: Container(
                color: Colors.white,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: const [
                    Spacer(),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class _MyClipper extends CustomClipper<Path> {
  final double space;

  _MyClipper(this.space);

  @override
  Path getClip(Size size) {
    final path = Path();
    final halfWidth = size.width / 2;
    final halfSpace = space / 2;
    final curve = space / 6;
    final height = halfSpace / 1.4;
    path.lineTo(halfWidth - halfSpace, 0);
    path.cubicTo(halfWidth - halfSpace, 0, halfWidth - halfSpace + curve,
        height, halfWidth, height);

    path.cubicTo(halfWidth, height, halfWidth + halfSpace - curve, height,
        halfWidth + halfSpace, 0);

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

    return path;
  }

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

Run Code Online (Sandbox Code Playgroud)

结果

在此输入图像描述

您只需要更新路径即可获得Container.