Home > Mobile >  how to draw a container like puzzle piece
how to draw a container like puzzle piece

Time:10-19

I want to create a Container widget like below. Can anybody help? enter image description here

CodePudding user response:

I'm using ShapeBorder,

class MyCardShape extends ShapeBorder {
  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.zero;

  @override
  ShapeBorder scale(double t) => this;

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    return getOuterPath(rect, textDirection: textDirection);
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    Path path = Path()..fillType = PathFillType.evenOdd;
    const radius = Radius.circular(16);

    final holeGap = rect.height * .15;

    final rrect = RRect.fromRectAndCorners(rect,
        bottomLeft: radius,
        bottomRight: radius,
        topLeft: radius,
        topRight: radius);

    final holePath = Path()
      ..addOval(
        Rect.fromCircle(
          center: Offset(rect.left, rect.top   rect.height / 2),
          radius: holeGap,
        ),
      )
      ..addOval(
        Rect.fromCircle(
          center: Offset(rect.right, rect.top   rect.height / 2),
          radius: holeGap,
        ),
      );

    final path1 = path
      ..addPath(holePath, Offset.zero)
      ..addRRect(rrect);

    final result = path1;
    return result;
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}
}

enter image description here

And using with ClipRRect to cover the extra shape, you can choose arcToPoint on paint or different methods.

class UITest extends StatelessWidget {
  const UITest({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.deepPurple,
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ClipRRect(
            // clipping extra
            child: Container(
              width: 400,
              height: 100,
              clipBehavior: Clip
                  .antiAlias, // not sure why this is not working on shape decoration
              decoration: ShapeDecoration(
                shape: MyCardShape(),
                color: Colors.amber,
              ),
            ),
          ),
        ),
      ),
    );
  }
}
  • Related