Widget TreeAdvanced50 XP4 min read
How does CustomPainter work and what are its performance considerations?
TL;DR: CustomPainter provides a Canvas API for arbitrary 2D drawing. Override paint() for drawing logic and shouldRepaint() to control when Flutter triggers a repaint.
Full Answer
CustomPainter gives you direct access to the Canvas API for drawing shapes, paths, text, and images. It's used in charting libraries, game UIs, and custom progress indicators.
- ▸paint(Canvas canvas, Size size) — draw here; called when shouldRepaint returns true
- ▸shouldRepaint(CustomPainter old) — return true only when drawing actually changes
- ▸hitTest(Offset position) — optional; return true if position is within a custom hit area
- ▸Passes a Listenable to CustomPaint(repaint:) to repaint on external changes (e.g., animation)
🎯
Pass your AnimationController as the repaint Listenable to CustomPaint. Flutter will call paint() on every tick without rebuilding the widget tree — very efficient.
Code Examples
dartAnimated circle with CustomPainter
Output
A blue arc that grows from the top as progress increases from 0.0 to 1.0
Common Mistakes
- ✗Returning true always from shouldRepaint — causes full repaint every frame even when nothing changed
- ✗Creating Paint objects inside paint() — create them as fields or in the constructor for efficiency
Interview Tip
💡
Show you understand the repaint Listenable pattern — it's a key performance optimization that separates CustomPainter beginners from experienced users.
#CustomPainter#Canvas#paint#drawing#performance