Search code examples
flutterflutter-layoutcontainersclip-path

ClipPath is not showing in Flutter with Container as child


I am working on a Flutter project Where in the interfaces I have made a few ClipPaths and one other Widget but But the ClipPath is not appearing on the output, all other Widgets are showing. Here is the code

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,
                  ),
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

I ahve made a CustomCLipper to make the custom paths. Here is the ShapeClipper class

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;
}

Here is the link to the output screenshot, Please help me resolve this issue

enter image description here


Solution

  • You didn't specify a height for the Containers placed in the ClipPath widget. Either, you need to specify height for it:

    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)
       ]),
    ),
    

    or, you need to wrap the ClipPath with Expanded widget:

    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)
          ]),
       ),
    ),