Home > Enterprise >  How to create a button with Custom Painter in Flutter?
How to create a button with Custom Painter in Flutter?

Time:03-22

I want to create a button with custom painter like this. I am new to flutter, so I think it can be achieved by custom painter.

ButtonImage

That is the code I have written, but it only designs the rectangle

class CurvePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Color(0xFFE32087)
      ..style = PaintingStyle.fill;

    final a = Offset(size.width * 2 / 1, size.height * 1 / 4);
    final b = Offset(size.width * 5 / 9, size.height * 3 / 4);
    final rect = Rect.fromPoints(a, b);
    final radius = Radius.circular(3);
    canvas.drawRRect(RRect.fromRectAndRadius(rect, radius), paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

CodePudding user response:

you can use somethink like this

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

    path.lineTo(size.width, 0);
    path.lineTo(size.width - 25, size.height);

    path.lineTo(0, size.height);

    return path;
  }

  @override
  bool shouldReclip(MyCustomClipper oldClipper) => false;
}

class CustomApp extends StatelessWidget {
  const CustomApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ClipPath(
              clipper: MyCustomClipper(),
              child: GestureDetector(
                onTap: () {
                  print("On Tap");
                },
                child: Container(
                  width: 80,
                  height: 50,
                  decoration: BoxDecoration(color: Colors.green, borderRadius: BorderRadius.circular(5)),
                  alignment: Alignment.centerLeft,
                  child: const Padding(
                    padding: EdgeInsets.only(left: 20.0),
                    child: Text(
                      "Buy",
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

Output

enter image description here

CodePudding user response:

You can use arcToPoint or quadraticBezierTo for this case. I think quadraticBezierTo looks better.

This paint is not totally perfect, but you can play with it.

class CurvePainter extends CustomPainter {
  /// corner side
  final double corner = 8.0;

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Color.fromARGB(255, 233, 80, 162)
      ..style = PaintingStyle.fill;

    final radius = Radius.circular(corner);
    Path path = Path()
      ..moveTo(corner, 0)
      ..lineTo(size.width - corner, 0)
      ..arcToPoint(
        //left top
        Offset(size.width, corner),
        radius: radius,
      )
      ..lineTo(size.width * .85, size.height - corner) //left bottom corner
      ..quadraticBezierTo(
        size.width * .85 - corner / 2,
        size.height,
        size.width * .85 - corner,
        size.height,
      )
      ..lineTo(corner, size.height)
      ..arcToPoint(
        Offset(0, size.height - corner),
        radius: radius,
      )
      ..lineTo(0, corner)
      ..arcToPoint(
        Offset(corner, 0),
        radius: radius,
      );

    canvas.drawPath(path, paint);
  }

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

Ans use

body: Center(
  child: SizedBox(
    height: 60,
    width: 100,
    child: CustomPaint(
      painter: CurvePainter(),
      child: const Align(
        alignment: Alignment(-.2, 0),
        child: Text("Buy"),
      ),
    ),
  ),
),

image

You can check more about Path and Align.

  • Related