'Flutter CustomClipper with Stroke Border

I want to create a Widget with 2 container using a CustomClipper and add a line/stroke/border between them like:

enter image description here

So I want a bottom border on the red colored Container, that is in between the red and the yellow container. I am able to add the clip path with a custom clipper, but I don't know how can I add a line in between these two container.

My current widget is:

Container(
      margin: const EdgeInsetsDirectional.only(end: 8),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(6),
        child: Stack(
          children: [
            Align(
              alignment: AlignmentDirectional.bottomCenter,
              child: Container(
                decoration: BoxDecoration(
                    color: Colors.yellow, border: Border.all(color: AppColors.instance.color0B0B0B, width: 1), borderRadius: const BorderRadius.all(Radius.circular(6))),
                height: 200,
                child: const Center(
                  child: Text("Hello"),
                ),
              ),
            ),
            Align(
              alignment: AlignmentDirectional.topCenter,
              child: ClipPath(
                clipper: MyClipper(),
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.red, border: Border.all(color: AppColors.instance.color0B0B0B, width: 1), borderRadius: const BorderRadius.all(Radius.circular(6))),
                  height: 200,
                  child: const Center(
                    child: Text("Hello Hello"),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    )

and the custom clipper class is:

class MyClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    int curveHeight = 60;
    Offset controlPoint = Offset(size.width / 2, size.height + curveHeight);
    Offset endPoint = Offset(size.width, size.height - curveHeight);

    Path path = Path()
      ..lineTo(0, size.height - curveHeight)
      ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, endPoint.dx, endPoint.dy)
      ..lineTo(size.width, 0)
      ..close();

    return path;
  }

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

If somebody have any other good idea, please correct me. Thanks in advance!



Solution 1:[1]

You can include another ClipPath on same position as red container with increasing its height a little but up.

height: 200 + 5, // main height + border

   body: LayoutBuilder(
        builder: (context, constraints) {
          return Center(
            child: Container(
              height: constraints.maxHeight,
              margin: const EdgeInsetsDirectional.only(end: 8),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(6),
                child: Stack(
                  children: [
                    Align(
                      alignment: AlignmentDirectional.bottomCenter,
                      child: Container(
                        decoration: BoxDecoration(
                            color: Colors.yellow,
                            border: Border.all(
                                // color: AppColors.instance.color0B0B0B,
                                width: 1),
                            borderRadius:
                                const BorderRadius.all(Radius.circular(6))),
                        height: constraints.maxHeight / 2,
                        child: const Center(
                          child: Text("Hello"),
                        ),
                      ),
                    ),

                    ///border color
                    Align(
                      alignment: AlignmentDirectional.topCenter,
                      child: ClipPath(
                        clipper: MyClipper(),
                        child: Container(
                          decoration: BoxDecoration(
                              color: Color.fromARGB(255, 38, 240, 16),
                              borderRadius:
                                  const BorderRadius.all(Radius.circular(6))),
                          height: constraints.maxHeight * .65 +
                              5, //  main height + border
                        ),
                      ),
                    ),
                    Align(
                      alignment: AlignmentDirectional.topCenter,
                      child: ClipPath(
                        clipper: MyClipper(),
                        child: Container(
                          decoration: const BoxDecoration(
                            color: Colors.red,
                            borderRadius: BorderRadius.all(
                              Radius.circular(6),
                            ),
                          ),
                          height: constraints.maxHeight * .65,
                          child: const Center(
                            child: Text("Hello Hello"),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      ),

enter image description here

It will still show blank space while using MyClipper while heigt<400(around)

Solution 2:[2]

You can use the CustomPainter class. There, you can specify strokeWidth and Color, and then make sure you give it the same path as your above curve.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Miroslav Blagoev