Search code examples
flutterdart

How to create curved widget without using border-radius in flutter


I'm a beginner of flutter development. I'm trying to create a curved widget using the border-radius component, but I'm not able to create an exact mockup screen. Please guide me on how to draw the curved widget. Here I have attached my mockup sample.

Thanks in advance.

enter image description here


Solution

  • Here is an example how you can achieve it using CustomClipper

    class ClippingApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: ClipPath(
            clipper: CurvedBottomClipper(),
            child: Container(
              color: Colors.lightGreen,
              height: 250.0,
              child: Center(
                  child: Padding(
                padding: EdgeInsets.only(bottom: 50),
                child: Text(
                  "Curved View",
                  style: TextStyle(
                    fontSize: 25,
                    color: Colors.white,
                  ),
                ),
              )),
            ),
          ),
        );
      }
    }
    
    class CurvedBottomClipper extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        // I've taken approximate height of curved part of view
        // Change it if you have exact spec for it
        final roundingHeight = size.height * 3 / 5;
    
        // this is top part of path, rectangle without any rounding
        final filledRectangle =
            Rect.fromLTRB(0, 0, size.width, size.height - roundingHeight);
    
        // this is rectangle that will be used to draw arc
        // arc is drawn from center of this rectangle, so it's height has to be twice roundingHeight
        // also I made it to go 5 units out of screen on left and right, so curve will have some incline there
        final roundingRectangle = Rect.fromLTRB(
            -5, size.height - roundingHeight * 2, size.width + 5, size.height);
    
        final path = Path();
        path.addRect(filledRectangle);
    
        // so as I wrote before: arc is drawn from center of roundingRectangle
        // 2nd and 3rd arguments are angles from center to arc start and end points
        // 4th argument is set to true to move path to rectangle center, so we don't have to move it manually
        path.arcTo(roundingRectangle, pi, -pi, true);
        path.close();
    
        return path;
      }
    
      @override
      bool shouldReclip(CustomClipper<Path> oldClipper) {
        // returning fixed 'true' value here for simplicity, it's not the part of actual question, please read docs if you want to dig into it
        // basically that means that clipping will be redrawn on any changes
        return true;
      }
    }
    

    And this is what you will get with this code: Curved rectangle screenshot