What are the main ways to build animations in Flutter?
Short Answer
Implicit animations (the `Animated*` widgets, like `AnimatedContainer`) animate a property change automatically with minimal code; explicit animations give full control via an `AnimationController` and `Tween`, for anything beyond a simple property tween.
Implicit animations are the fast path: wrap a value in `AnimatedContainer`, `AnimatedOpacity`, etc., change the target value (e.g. a new `color` or `width`), and Flutter animates the transition automatically over the given `duration` — no controller needed. This covers most simple "animate this property when it changes" cases.
Explicit animations give you precise control: you create an `AnimationController` (which drives a value over time, typically 0 to 1), wrap it in a `Tween` to map that range onto the actual values you want (e.g. a color or a rotation), and rebuild via `AnimatedBuilder` whenever the controller ticks. This is necessary for coordinating multiple animations, repeating/reversing animations, responding to gestures mid-animation, or anything an implicit widget doesn't expose a parameter for. There's also the newer declarative animation API for Flutter's animated transitions between routes/widgets, but controller-based explicit animation remains the foundation for complex custom motion.
Code Example
class _FadeInState extends State<FadeIn> with SingleTickerProviderStateMixin {
late final _controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
)..forward();
late final _opacity = CurvedAnimation(parent: _controller, curve: Curves.easeIn);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) =>
FadeTransition(opacity: _opacity, child: widget.child);
}Common Mistakes
- ×Forgetting to `dispose()` an `AnimationController`, leaking the ticker.
- ×Reaching for explicit `AnimationController` setup when an `Animated*` implicit widget would do the job in two lines.
Related Questions
What is CustomPainter used for?
CustomPainter lets you draw directly onto a canvas with low-level drawing primitives (paths, arcs, text, gradients) for visuals that no combination of standard widgets can produce — charts, custom shapes, signature pads.
How does Flutter manage memory, and how do you avoid leaks?
Dart uses automatic garbage collection, so you don't free memory manually — leaks in Flutter almost always come from long-lived objects (controllers, streams, listeners) holding references that prevent disposed widgets' resources from being collected.