Flutter › Custom Painters & CustomPaint

How can you combine a CustomPainter with an AnimationController to create a smoothly animated custom drawing that changes over time?

Intermediate

Answer

Combining a CustomPainter with an AnimationController lets you create a genuinely animated custom drawing by having the painter's drawing logic reference the animation controller's current value, which changes smoothly over time, and repainting the canvas on every single animation frame update, meaning something like a custom loading spinner, an animated chart, or a progress indicator can be drawn with exactly the specific visual style your design calls for, while still being smoothly animated over time just like Flutter's own standard built in animated widgets.
class SpinnerPainter extends CustomPainter {
  final double animationValue;
  SpinnerPainter(this.animationValue);

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawArc(Offset.zero & size, 0, animationValue * 2 * 3.14159, false, paint);
  }

  @override
  bool shouldRepaint(covariant SpinnerPainter oldDelegate) => oldDelegate.animationValue != animationValue;
}
Real-world example A custom branded loading indicator uses an AnimationController driving a CustomPainter that draws a continuously rotating arc, achieving a completely unique visual style specifically matching the app's own distinct brand identity.

Common follow-ups: How do you properly dispose of an AnimationController to avoid a memory leak?;What is the difference between using AnimatedBuilder together with CustomPaint versus rebuilding an entire StatefulWidget on every frame?