How can I change the color of a drawn object using CustomPainter in Flutter?

341 Views Asked by At

Currently I have a CustomPainter that is using the touchable flutter package

class MapPainter extends CustomPainter {

  final BuildContext context;
  MapPainter(this.context);

  @override
  void paint(Canvas canvas, Size size) {
    var myCanvas = TouchyCanvas(context,canvas);
    // Create a Paint object to draw the smiley face
    var paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;
      
    // Draw the face
    myCanvas.drawCircle(
      Offset(size.width / 2, size.height / 2),
      size.width / 2,
      paint,
    );

    // Draw the eyes 
    myCanvas.drawCircle(
      Offset(size.width * 0.25, size.height * 0.25),
      size.width * 0.1,
      paint,
      onTapDown: (tapdetail) {
        print("Touched");
        
      }
    );
   
  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

OnTapDown I want to be able to change the color of the eyes.

I am new to using CustomPainter so I'm not sure on how to redraw the same painter with different colors and have not been able to find anyone doing it using the touchable package.

1

There are 1 best solutions below

1
On

First of all, do not pass the context inside and operate with concrete data by passing it from the parent.

In your case, concentrate data is the color.

And try to make repainting as optimal as possible. For your case, repaint only if color has been changed. Below is an example of your CustomPainter

class MapPainter extends CustomPainter {
  final Color _eyeColor;

  const MapPainter({Color? eyeColor}): _eyeColor = eyeColor ?? Colors.red;

  @override
  void paint(Canvas canvas, Size size) {
    // Create a Paint object to draw the smiley face
    var paint = Paint()
      ..color = _eyeColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;

    // Draw the face
    canvas.drawCircle(
      Offset(size.width / 2, size.height / 2),
      size.width / 2,
      paint,
    );

    // Draw the eyes
    canvas.drawCircle(
        Offset(size.width * 0.25, size.height * 0.25),
        size.width * 0.1,
        paint
    );

    canvas.drawCircle(
        Offset(size.width * 0.75, size.height * 0.25),
        size.width * 0.1,
        paint
    );
  }

  @override
  bool shouldRepaint(covariant MapPainter oldDelegate) {
    return _eyeColor != oldDelegate._eyeColor;
  }
}

For passing the color use StatefullWidget:

class MyClickableWidget extends StatefulWidget {
  const MyClickableWidget({Key? key}) : super(key: key);

  @override
  State<MyClickableWidget> createState() => _MyClickableWidgetState();
}

class _MyClickableWidgetState extends State<MyClickableWidget> {
  final Color _oddColor = Colors.green;
  final Color _evenColor = Colors.blue;
  bool _isOdd = true;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(() {
        _isOdd = !_isOdd;
      }),
      child: CustomPaint(
        painter: MapPainter(eyeColor: _isOdd ? _oddColor : _evenColor),
        child: Container(),
      ),
    );
  }
}

enter image description here