ClipPath 未显示在 Flutter 中,Container 作为子项

ClipPath is not showing in Flutter with Container as child

我正在开发一个 Flutter 项目,在界面中我制作了一些 ClipPaths 和一个其他小部件,但是 ClipPath 没有出现在输出中,所有其他 Widgets 正在显示。 这是代码

class HeaderWidget extends StatefulWidget {
  double height;
  bool showIcon;
  IconData icon;

  HeaderWidget({
    Key? key,
    required this.height,
    required this.showIcon,
    required this.icon,
  }) : super(key: key);

  @override
  // ignore: no_logic_in_create_state
  _HeaderWidgetState createState() =>
      // ignore: no_logic_in_create_state
      _HeaderWidgetState(height, icon, showIcon);
}

class _HeaderWidgetState extends State<HeaderWidget> {
  double height;
  bool showIcon;
  IconData icon;

  _HeaderWidgetState(this.height, this.icon, this.showIcon);

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    return SafeArea(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          ClipPath(
            child: Container(
              decoration: const BoxDecoration(
                gradient: LinearGradient(
                  colors: [
                    Colors.teal,
                    Colors.tealAccent,
                  ],
                  begin: FractionalOffset(0.0, 0.0),
                  end: FractionalOffset(1.0, 0.0),
                  stops: [0.0, 1.0],
                  tileMode: TileMode.clamp,
                ),
              ),
            ),
            clipper: ShapeClipper(offsets: [
              Offset(width / 5, height),
              Offset(width / 10 * 5, height - 60),
              Offset(width / 5 * 4, height + 20),
              Offset(width, height - 20)
            ]),
          ),
          ClipPath(
            child: Container(
              decoration: const BoxDecoration(
                gradient: LinearGradient(
                  colors: [
                    Colors.teal,
                    Colors.tealAccent,
                  ],
                  begin: FractionalOffset(0.0, 0.0),
                  end: FractionalOffset(1.0, 0.0),
                  stops: [0.0, 1.0],
                  tileMode: TileMode.clamp,
                ),
              ),
            ),
            clipper: ShapeClipper(offsets: [
              Offset(width / 4, height),
              Offset(width / 2, height - 40),
              Offset(width / 5 * 4, height - 80),
              Offset(width, height - 16)
            ]),
          ),
          ClipPath(
            child: Container(
              decoration: const BoxDecoration(
                gradient: LinearGradient(
                  colors: [
                    Colors.teal,
                    Colors.tealAccent,
                  ],
                  begin: FractionalOffset(0.0, 0.0),
                  end: FractionalOffset(1.0, 0.0),
                  stops: [0.0, 1.0],
                  tileMode: TileMode.clamp,
                ),
              ),
            ),
            clipper: ShapeClipper(offsets: [
              Offset(width / 3, height),
              Offset(width / 10, height - 20),
              Offset(width / 2, height - 30),
              Offset(width, height)
            ]),
          ),
          Visibility(
            visible: showIcon,
            child: SizedBox(
              height: height - 40,
              child: Center(
                child: Container(
                  margin: const EdgeInsets.all(20),
                  padding: const EdgeInsets.only(
                      left: 15, right: 15, top: 15, bottom: 15),
                  decoration: BoxDecoration(
                      borderRadius: const BorderRadius.only(
                        topLeft: Radius.circular(60),
                        topRight: Radius.circular(60),
                        bottomLeft: Radius.circular(60),
                        bottomRight: Radius.circular(60),
                      ),
                      border: Border.all(color: Colors.black, width: 5)),
                  child: Icon(
                    icon,
                    color: Colors.black,
                    size: 40,
                  ),
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

我已经 CustomCLipper 制作了自定义路径。这里是ShapeClipperclass

class ShapeClipper extends CustomClipper<Path> {
  List<Offset> offsets;
  ShapeClipper({
    required this.offsets,
  });

  @override
  Path getClip(Size size) {
    var path = Path();
    path.lineTo(0.0, size.height - 20);
    path.quadraticBezierTo(
        offsets[0].dx, offsets[0].dy, offsets[1].dx, offsets[1].dy);
    path.quadraticBezierTo(
        offsets[2].dx, offsets[2].dy, offsets[3].dx, offsets[3].dy);
    path.lineTo(size.width, 0.0);
    path.close();
    return path;
  }

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

这是link输出截图,请帮我解决这个问题

您没有为放置在 ClipPath 小部件中的容器指定高度。或者,您需要为其指定高度:

ClipPath(
   child: Container(
      height: 30,
      decoration: const BoxDecoration(
         gradient: LinearGradient(
            colors: [
               Colors.teal,
               Colors.tealAccent,
            ],
            begin: FractionalOffset(0.0, 0.0),
            end: FractionalOffset(1.0, 0.0),
            stops: [0.0, 1.0],
            tileMode: TileMode.clamp,
         ),
      ),
   ),
   clipper: ShapeClipper(offsets: [
      Offset(width / 5, height),
      Offset(width / 10 * 5, height - 60),
      Offset(width / 5 * 4, height + 20),
      Offset(width, height - 20)
   ]),
),

或者,您需要使用 Expanded 小部件包装 ClipPath:

Expanded(
   child: ClipPath(
      child: Container(
         decoration: const BoxDecoration(
            gradient: LinearGradient(
               colors: [
                  Colors.teal,
                  Colors.tealAccent,
               ],
               begin: FractionalOffset(0.0, 0.0),
               end: FractionalOffset(1.0, 0.0),
               stops: [0.0, 1.0],
               tileMode: TileMode.clamp,
            ),
         ),
      ),
      clipper: ShapeClipper(offsets: [
         Offset(width / 5, height),
         Offset(width / 10 * 5, height - 60),
         Offset(width / 5 * 4, height + 20),
         Offset(width, height - 20)
      ]),
   ),
),