Search code examples
flutterflutter-layout

Flutter make a simple Ticket widget


In flutter i want to clip optional part of Container to make this widget:

enter image description here

clipping the widget to have two semicircle on top and bottom of that.

for some feature of this clipped widget i want to have some optional feature, for example:

enter image description here

clipping top, bottom of that optional and space from right. how can i clipping Container with optional feature?


Solution

  • you can use custom clipper + arcToPoint path method to create clean arcs.

    Like that:

    enter image description here

    import 'package:flutter/material.dart';
    import 'package:vector_math/vector_math.dart' as v_math;
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
            body: SafeArea(
              child: MyHomePage(),
            ),
          ),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
          ClipPath(
            clipper: DolDurmaClipper(right: 40, holeRadius: 20),
            child: Container(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(
                  Radius.circular(15),
                ),
                color: Colors.blueAccent,
              ),
              width: 300,
              height: 95,
              padding: EdgeInsets.all(15),
              child: Text('first example'),
            ),
          ),
          SizedBox(
            height: 20,
          ),
          ClipPath(
            clipper: DolDurmaClipper(right: 100, holeRadius: 40),
            child: Container(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(
                  Radius.circular(15),
                ),
                color: Colors.amber,
              ),
              width: 200,
              height: 250,
              padding: EdgeInsets.all(35),
              child: Text('second example'),
            ),
          ),
        ]);
      }
    }
    
    class DolDurmaClipper extends CustomClipper<Path> {
      DolDurmaClipper({@required this.right, @required this.holeRadius});
    
      final double right;
      final double holeRadius;
    
      @override
      Path getClip(Size size) {
        final path = Path()
          ..moveTo(0, 0)
          ..lineTo(size.width - right - holeRadius, 0.0)
          ..arcToPoint(
            Offset(size.width - right, 0),
            clockwise: false,
            radius: Radius.circular(1),
          )
          ..lineTo(size.width, 0.0)
          ..lineTo(size.width, size.height)
          ..lineTo(size.width - right, size.height)
          ..arcToPoint(
            Offset(size.width - right - holeRadius, size.height),
            clockwise: false,
            radius: Radius.circular(1),
          );
    
        path.lineTo(0.0, size.height);
    
        path.close();
        return path;
      }
    
      @override
      bool shouldReclip(DolDurmaClipper oldClipper) => true;
    }