Question #351HardWidgets & UI

What is a CustomPainter in Flutter?

#widget#custompainter#rendering

Answer

Overview

text
CustomPainter
allows you to draw completely custom graphics directly onto the canvas using low-level drawing APIs — lines, arcs, circles, paths, text, and images.


Basic CustomPainter

dart
class CirclePainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;

    canvas.drawCircle(
      Offset(size.width / 2, size.height / 2), // Center
      size.width / 3,                           // Radius
      paint,
    );
  }

  
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

// Usage
CustomPaint(
  size: Size(200, 200),
  painter: CirclePainter(),
)

Drawing Multiple Shapes

dart
class ShapesPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final fillPaint = Paint()..color = Colors.blue;
    final strokePaint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 3;

    // Rectangle
    canvas.drawRect(Rect.fromLTWH(20, 20, 100, 60), fillPaint);

    // Circle
    canvas.drawCircle(Offset(180, 50), 40, strokePaint);

    // Line
    canvas.drawLine(Offset(0, 120), Offset(size.width, 120), strokePaint);

    // Custom Path
    final path = Path()
      ..moveTo(size.width / 2, 140)
      ..lineTo(size.width - 20, 200)
      ..lineTo(20, 200)
      ..close();
    canvas.drawPath(path, fillPaint..color = Colors.green);
  }

  
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

Animated CustomPainter

dart
class ArcPainter extends CustomPainter {
  final double progress; // 0.0 to 1.0
  ArcPainter(this.progress);

  
  void paint(Canvas canvas, Size size) {
    final bgPaint = Paint()
      ..color = Colors.grey[300]!
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10;

    final fgPaint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10
      ..strokeCap = StrokeCap.round;

    final rect = Rect.fromCircle(
      center: Offset(size.width / 2, size.height / 2),
      radius: size.width / 2 - 10,
    );

    canvas.drawArc(rect, -3.14 / 2, 2 * 3.14, false, bgPaint);
    canvas.drawArc(rect, -3.14 / 2, 2 * 3.14 * progress, false, fgPaint);
  }

  
  bool shouldRepaint(ArcPainter oldDelegate) => oldDelegate.progress != progress;
}

// In widget with animation
CustomPaint(
  size: Size(200, 200),
  painter: ArcPainter(_controller.value),
)

Canvas Drawing Methods

MethodWhat it draws
text
drawCircle
Circle
text
drawRect
Rectangle
text
drawRRect
Rounded rectangle
text
drawLine
Straight line
text
drawPath
Custom path/shape
text
drawArc
Arc or pie segment
text
drawImage
Bitmap image
text
drawParagraph
Styled text
text
drawOval
Oval/ellipse
text
drawPoints
Individual points

shouldRepaint

dart

bool shouldRepaint(ArcPainter oldDelegate) {
  // Return true if something changed that needs redrawing
  return oldDelegate.progress != progress;
  // Return false if the painting won't change
}

Use Cases: Progress indicators, charts, custom shapes, signature pads, drawing apps, custom gauges. For complex graphics, consider using

text
flutter_custom_paint
or canvas libraries like
text
fl_chart
.