Answer
Overview
allows you to draw completely custom graphics directly onto the canvas using low-level drawing APIs — lines, arcs, circles, paths, text, and images.textCustomPainter
Basic CustomPainter
dartclass 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
dartclass 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
dartclass 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
| Method | What it draws |
|---|---|
text | Circle |
text | Rectangle |
text | Rounded rectangle |
text | Straight line |
text | Custom path/shape |
text | Arc or pie segment |
text | Bitmap image |
text | Styled text |
text | Oval/ellipse |
text | Individual points |
shouldRepaint
dartbool 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
or canvas libraries liketextflutter_custom_paint.textfl_chart