How to Create Animation in Flutter: Simple Guide
To create animation in Flutter, use
AnimationController to control the animation timing and AnimatedBuilder or AnimatedWidget to rebuild UI during animation. Initialize the controller in a StatefulWidget, define animation properties, and start the animation with controller.forward().Syntax
Flutter animations typically use AnimationController to manage animation timing and AnimatedBuilder to rebuild widgets when the animation value changes.
Key parts:
AnimationController(vsync, duration): Controls animation progress.Animation: Defines the animation value (e.g., tween).AnimatedBuilder: Rebuilds UI on animation updates.vsync: Prevents offscreen animations from consuming resources.
dart
class MyAnimationWidget extends StatefulWidget { @override _MyAnimationWidgetState createState() => _MyAnimationWidgetState(); } class _MyAnimationWidgetState extends State<MyAnimationWidget> with SingleTickerProviderStateMixin { late AnimationController controller; @override void initState() { super.initState(); controller = AnimationController(vsync: this, duration: const Duration(seconds: 2)); controller.forward(); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container(); } }
Example
This example shows a simple animation that changes the size of a blue square from 0 to 200 pixels over 2 seconds.
dart
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp(home: AnimationExample()); } } class AnimationExample extends StatefulWidget { const AnimationExample({super.key}); @override State<AnimationExample> createState() => _AnimationExampleState(); } class _AnimationExampleState extends State<AnimationExample> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _animation; @override void initState() { super.initState(); _controller = AnimationController(vsync: this, duration: const Duration(seconds: 2)); _animation = Tween<double>(begin: 0, end: 200).animate(_controller); _controller.forward(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Flutter Animation Example')), body: Center( child: AnimatedBuilder( animation: _animation, builder: (context, child) { return Container( width: _animation.value, height: _animation.value, color: Colors.blue, ); }, ), ), ); } }
Output
A blue square grows smoothly from 0 to 200 pixels in width and height over 2 seconds in the center of the screen.
Common Pitfalls
Common mistakes when creating animations in Flutter include:
- Not disposing the
AnimationController, which causes memory leaks. - Forgetting to add
with SingleTickerProviderStateMixinto the state class, which is needed forvsync. - Not calling
controller.forward()orcontroller.repeat()to start the animation. - Using
setState()unnecessarily instead ofAnimatedBuilderorAnimatedWidgetfor efficient rebuilds.
dart
/* Wrong: Missing dispose and vsync */ class WrongAnimation extends StatefulWidget { @override _WrongAnimationState createState() => _WrongAnimationState(); } class _WrongAnimationState extends State<WrongAnimation> { late AnimationController controller; @override void initState() { super.initState(); controller = AnimationController(vsync: null, duration: const Duration(seconds: 1)); // Missing vsync controller.forward(); } @override Widget build(BuildContext context) { return Container(); } } /* Right: Proper dispose and vsync */ class RightAnimation extends StatefulWidget { @override _RightAnimationState createState() => _RightAnimationState(); } class _RightAnimationState extends State<RightAnimation> with SingleTickerProviderStateMixin { late AnimationController controller; @override void initState() { super.initState(); controller = AnimationController(vsync: this, duration: const Duration(seconds: 1)); controller.forward(); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container(); } }
Quick Reference
Animation basics cheat sheet:
| Class/Method | Purpose |
|---|---|
AnimationController | Controls animation timing and progress |
Tween | Defines value range for animation |
AnimatedBuilder | Rebuilds UI when animation changes |
vsync | Optimizes animation resource usage |
controller.forward() | Starts animation forward |
controller.dispose() | Frees resources when done |
| Class/Method | Purpose |
|---|---|
| AnimationController | Controls animation timing and progress |
| Tween | Defines value range for animation |
| AnimatedBuilder | Rebuilds UI when animation changes |
| vsync | Optimizes animation resource usage |
| controller.forward() | Starts animation forward |
| controller.dispose() | Frees resources when done |
Key Takeaways
Use AnimationController with vsync to manage animation timing efficiently.
Wrap animated widgets with AnimatedBuilder to rebuild only when animation changes.
Always dispose AnimationController in the dispose() method to avoid memory leaks.
Start animations by calling controller.forward() or controller.repeat().
Use Tween to define the range of animated values.