'Flutter button with custom shape - (triangle)

I've created a circular button which in this case is RawMaterialButton and I'm trying to use CustomPaint to create a triangle shape in the centre of it, but it's saying ShapesPainter is not defined for the class ClearButton'. I tried other buttons but couldn't get any of them to acceptShapesPainter`.

RawMaterialButton(
          child: CustomPaint(
            painter: ShapesPainter(),
            child: Container(
              height: 40,
            ),
          ),
          onPressed: onPressed,
          constraints: BoxConstraints.tightFor(
            width: 90.0,
            height: 90.0,
          ),
          shape: RoundedRectangleBorder(),
          fillColor: Colors.transparent,
        )

Which button type should be used with ShapesPainter or how can I otherwise create a circular button with a triangle or another shape in the centre?

This is the button I was trying to create which as you can see is basically a circular button with a triangle.

enter image description here



Solution 1:[1]

create CustomClipper

class CustomTriangleClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(0, 0);
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}

and then Usage :

ClipPath(
    clipper: CustomTriangleClipper(),
    child: Container(
      width: 50,
      height: 50,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.bottomLeft,
          end: Alignment.topRight,
          colors: [Color(0xffF25D50), Color(0xffF2BB77)],
        ),
      ),
    ),
  );

Solution 2:[2]

Below is the code which you can refer.

class MyButton extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Offset centerPoint = Offset(100, 100);
    double radius = 60;
    double triangleA = 35;   // this the dimension of triangle's side
    double triangleR = triangleA / sqrt(3.0);   // this the distance between the center of triangle/circle to corner of triangle

    // I am drawing here circle, while you can draw your shape as per your convenience.
    canvas.drawCircle(
        centerPoint,
        radius,
        Paint()
          ..color = Colors.grey[700]
          ..style = PaintingStyle.fill);

    Path path = Path();

    double x1Point = centerPoint.dx + triangleR * cos(3 * pi / 2);
    double y1Point = centerPoint.dy + triangleR * sin(3 * pi / 2);
    path.moveTo(x1Point, y1Point);

    double x2Point = centerPoint.dx +
        triangleR * cos((3 * pi / 2) - Angle.fromDegrees(120).radians);
    double y2Point = centerPoint.dy +
        triangleR * sin((3 * pi / 2) - Angle.fromDegrees(120).radians);
    path.lineTo(x2Point, y2Point);

    double x3Point = centerPoint.dx +
        triangleR * cos((3 * pi / 2) + Angle.fromDegrees(120).radians);
    double y3Point = centerPoint.dy +
        triangleR * sin((3 * pi / 2) + Angle.fromDegrees(120).radians);
    path.lineTo(x3Point, y3Point);

    path.close();

    canvas.drawPath(
        path,
        Paint()
          ..color = Colors.deepOrange
          ..style = PaintingStyle.fill);

    canvas.save();
    canvas.restore();
  }
RawMaterialButton(
 child: CustomPaint(
   painter: MyButton(),
   child: GestureDetector(
     onTap: () {
        print('Here, you can handle button click event');
     },
   ),
 ),
 onPressed: () {
 },
)

Solution 3:[3]

This is my version, can specify rotation, and color

class TrianglePainter extends CustomPainter {
  double sideSize;

  Color color;
  TrianglePainter({required this.sideSize, required this.color});

  @override
  void paint(Canvas canvas, Size size) {
    double ySize = sideSize * cos(30 * pi / 180);
    double xSize = sideSize;

    double point0x = xSize / 2;
    double point0y = ySize / 2;

    double point1x = -xSize / 2;
    double point1y = ySize / 2;

    double point2x = 0;
    double point2y = -ySize / 2;

    Path path = Path();
    path.moveTo(point0x, point0y);
    path.lineTo(point1x, point1y);
    path.lineTo(point2x, point2y);
    path.lineTo(point0x, point0y);
    path.close();
    canvas.drawPath(
        path,
        Paint()
          ..color = color
          ..style = PaintingStyle.fill);

    canvas.save();
    canvas.restore();
  }

  @override
  bool shouldRepaint(TrianglePainter oldDelegate) {
    return oldDelegate.color != color || oldDelegate.sideSize != sideSize;
  }
}

Widget triangle(double sideSize, Color color, double angle) {
  return Transform.rotate(
      child: CustomPaint(
        painter: TrianglePainter(
          color: color,
          sideSize: sideSize,
        ),
      ),
      angle: angle * pi / 180);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mohammad
Solution 2
Solution 3 Hairy Ass