flutterdartcustom-painting

Custom Paint Button in Flutter


I'm trying to make a collection of hexagonal buttons in my flutter app, but I can't get it working.

I've tried a couple different things with CustomPaint and the ClipPath class, but my widgets either don't render correctly or don't detect any input. Does anyone have some advice on what the best practices to do here would be? Here's something I've tried:

        Container(
          child: ClipPath(
            clipper: CustomHexagonClipper(Offset(0, 0), hexagonRadius),
            child: GestureDetector(
              onTap: () => print("Button clicked!"),
              child: CustomPaint(
                painter: HexagonPainter(Offset(0, 0), hexagonRadius),
              ),
            )
          ),
        ),

CustomHexagonClipper is a CustomClipper that draws a hexagon shape and HexagonPainter is the CustomPainter class I'm using.

Thank you!


Solution

  • You can use ShapeBorder for CustomBorder, just handle the path . this ShapeBorder can be used on many widgets like Container, Material, InkWell....

    Shape

    class HexagonShape extends OutlinedBorder {
      @override
      OutlinedBorder copyWith({BorderSide? side}) => this; //todo
    
      @override
      Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
        return getOuterPath(rect);
      }
    
      @override
      Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
        Path path = Path();
        path.moveTo(rect.left + rect.width / 4, rect.top);
        path.lineTo(rect.right - rect.width / 4, rect.top);
        path.lineTo(rect.right, rect.top + rect.height / 2);
        path.lineTo(rect.right - rect.width / 4, rect.bottom);
        path.lineTo(rect.left + rect.width / 4, rect.bottom);
        path.lineTo(rect.left, rect.top + rect.height / 2);
        path.close();
        return path;
      }
    
      @override
      void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
        // TODO: implement paint
      }
    
      @override
      ShapeBorder scale(double t) => this;
    }
    
    Container(
      height: 100,
      width: 100,
      decoration:
          ShapeDecoration(shape: HexagonShape(), color: Colors.red),
    ),
    ElevatedButton(
      style: ElevatedButton.styleFrom(
        shape: HexagonShape(),
        fixedSize: Size(100, 100),
      ),
      onPressed: () {},
      child: Center(
        child: Text(
          "Hello",
          style: TextStyle(
            color: Colors.white,
            fontSize: 20,
          ),
        ),
      ),
    )
    

    enter image description here