How to make a container of a shape given below in flutter with height = 130 and width = 300

Viewed 383

How to make a container having shape like the image shown below.

width = 300 and height = 130

The Two semicircles should be aligned at centre of the height of container

Please click on "Card" to see image Card

2 Answers

You need to use custom clippers.

Here's an example on that,

class CardClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final Path path = Path();

    path.lineTo(0.0, size.height / 2 - 4);
    path.relativeArcToPoint(const Offset(0, 30),
        radius: const Radius.circular(10.0), largeArc: true);
    path.lineTo(0.0, size.height);
    path.lineTo(size.width, size.height);
    path.lineTo(size.width, size.height / 2 + 26);
    path.arcToPoint(Offset(size.width, size.height / 2 - 4),
        radius: const Radius.circular(10.0), clockwise: true);
    path.lineTo(size.width, 0);
    path.lineTo(0.0, 0.0);
    return path;
  }

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

Okay, that's about the clipper, we can now use it, but it won't provide us with shadow.

To cast shadows to clipper objects, we'll use Clip Shadow package.

Now, we'll implement CardClipper with actual Clip Widget, in this case, ClipShadow,

ClipShadow(
  clipper: CardClipper(),
  boxShadow: [
      BoxShadow(
        offset: Offset(0, 4),
        blurRadius: 18,
        color: Color.fromRGBO(0, 0, 0, 0.1)),
  ],
  child: Card(...)
);

Try playing with values in the clipper until you get the desired output.

You can try with custom painter.

import 'package:flutter/material.dart';
import 'dart:math' as math;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  DateTime date = DateTime.now();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white54,
      body: SafeArea(
        child: Container(
          child: Center(
            child: Container(
              decoration: BoxDecoration(
                color: Colors.green,
                borderRadius: BorderRadius.circular(10)
              ),

                height: 100,
                width: 200,
                child: Stack(
                  clipBehavior: Clip.antiAlias,
                  children: [
                    Positioned(
                        left: -15,
                        bottom: 35,
                        child: Container(
                          height: 30,
                          width: 30,
                          child: CustomPaint(
                            painter: MyPainter(),
                          ),
                        )),
                    Positioned(
                      right: -15,
                      bottom: 30.5,
                      child: Container(
                        height: 30,
                        width: 35,
                        child: CustomPaint(
                          painter: MyPainter(),
                        ),
                      ),
                    )
                  ],
                )),
          ),
        ),
      ),
    );
  }
}

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()..color = Colors.white;
    canvas.drawArc(
      Rect.fromCenter(
        center: Offset(size.height / 2, size.width / 2),
        height: size.height,
        width: size.width,
      ),
      math.pi * 2,
      math.pi * 2,
      true,
      paint,
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

output:

enter image description here

N.B: Adjust your color and circle height and width as you need

Related