How to make custom circle in Flutter

Viewed 174

I got a project from a client and the UI looks like this: enter image description here

I have a problem creating the gradient circle background. My code looks like this:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Container(
            decoration: BoxDecoration(
              gradient: gradient,
              borderRadius: BorderRadius.only(
                bottomLeft: const Radius.circular(1500.0),
                bottomRight: const Radius.circular(1500.0),
              ),
            ),
            height: 450,
            child: Center(
              child: Container(
                width: 195,
                height: 195,
                decoration: BoxDecoration(
                  color: Colors.white,
                  shape: BoxShape.circle,
                ),
                child: Image.asset(
                  'assets/logo_new.png',
                  width: 200,
                ),
              ),
            ),
          ),
          Container()
        ],
      ),
    );
  }

and it looks like this: enter image description here

Can anyone help me creating the circle gradient background and positioning the white circle on the bottom of it

ps: This is my first time asking in StackOverflow, so I'm sorry if my question doesn't make sense. Thank you!

2 Answers

use stack widget

Scaffold(
      body: Column(
        children: [
          Container(
            height: 550,
            child: Stack(
              alignment: AlignmentDirectional.bottomCenter,
              children: [
                Positioned( // <-- blue container
                  top: 0,
                  child: Container(
                    height: 450,
                    width: MediaQuery.of(context).size.width,
                    decoration: BoxDecoration(
                      gradient: new LinearGradient(
                          colors: [
                            const Color(0xFF3366FF),
                            const Color(0xFF00CCFF),
                          ],
                          begin: const FractionalOffset(0.0, 0.0),
                          end: const FractionalOffset(1.0, 0.0),
                          stops: [0.0, 1.0],
                          tileMode: TileMode.clamp),
                      borderRadius: BorderRadius.only(
                        bottomLeft: const Radius.circular(1500.0),
                        bottomRight: const Radius.circular(1500.0),
                      ),
                    ),
                  ),
                ),
                Positioned(//<-- image container
                  bottom: 0,
                  child: Container(
                    width: 200,
                    height: 200,
                    padding: EdgeInsets.all(20),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      shape: BoxShape.circle,
                    ),
                    child: Container(
                      width: 195,
                      height: 195,
                      decoration: BoxDecoration(
                        color: Colors.yellow,
                        shape: BoxShape.circle,
                      ),
                      child: Image.asset(
                        MyResources.cameraPng, //<-- image path
                        width: 200,
                      ),
                    ),
                  ),
                ),
                Positioned(// <-- text
                  top: 150,
                  child: Text(
                    'HELLO   !',
                    style: TextStyle(fontSize: 55, color: Colors.white),
                  ),
                ),
              ],
            ),
          ),
          Container( //<-- button is here
            width: 300,
            height: 50,
            color: Colors.red,
            child: Center(
              child: Text('your button',
                  style: TextStyle(fontSize: 20, color: Colors.white)),
            ),
          )
        ],
      ),
    );

enter image description here

I would rather go with a Positioned widget inside a Stack and use MediaQuery.of(context).size to calculate position and size of you gradient box based on phone screen size. The following will draw a big circle that is partly outside the screen. You can adjust the formulas to fine tune.

Note: this will do what you need in portait, in landscape it will be different. If you need different, either find out how to create formulas with MediaQuery to match landscape as well, or check out OrientationBuilder widget and use different versions in portrait and landscape.

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Stack(
      children: [
        Positioned(
            left: (MediaQuery.of(context).size.width -
                    MediaQuery.of(context).size.height) /
                2,
            top: -1 * MediaQuery.of(context).size.height / 2,
            child: Container(
              width: MediaQuery.of(context).size.height,
              height: MediaQuery.of(context).size.height,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                gradient: gradient,
              ),
            )),
        Center(
          child: Container(
            width: 195,
            height: 195,
            decoration: BoxDecoration(
              color: Colors.white,
              shape: BoxShape.circle,
            ),
            child: Image.asset(
                'assets/logo_new.png',
                 width: 200,
            ),
          ),
        )
      ],
    )
  );
}
Related