Staggered animations help make your app look smooth and interesting by playing multiple animations one after another with small delays.
Staggered animations in Flutter
AnimationController controller = AnimationController(vsync: this, duration: Duration(seconds: 2)); Animation<double> animation1 = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.0, 0.5, curve: Curves.easeIn), ), ); Animation<double> animation2 = Tween(begin: 0.0, end: 100.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.5, 1.0, curve: Curves.easeOut), ), );
The Interval defines when each animation starts and ends within the total duration.
Use AnimationController to control the timing of all animations together.
AnimationController controller = AnimationController(vsync: this, duration: Duration(seconds: 3)); Animation<double> fadeIn = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.0, 0.3), ), );
Animation<double> moveRight = Tween(begin: 0.0, end: 200.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.3, 0.7, curve: Curves.easeInOut), ), );
Animation<double> fadeOut = Tween(begin: 1.0, end: 0.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.7, 1.0, curve: Curves.easeOut), ), );
This app shows a blue square that first fades in during the first half of 3 seconds, then grows bigger during the second half.
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: Scaffold( body: Center( child: StaggeredAnimationWidget(), ), ), ); } } class StaggeredAnimationWidget extends StatefulWidget { const StaggeredAnimationWidget({super.key}); @override State<StaggeredAnimationWidget> createState() => _StaggeredAnimationWidgetState(); } class _StaggeredAnimationWidgetState extends State<StaggeredAnimationWidget> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _opacityAnimation; late Animation<double> _sizeAnimation; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(seconds: 3), ); _opacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: _controller, curve: const Interval(0.0, 0.5, curve: Curves.easeIn), ), ); _sizeAnimation = Tween<double>(begin: 50.0, end: 150.0).animate( CurvedAnimation( parent: _controller, curve: const Interval(0.5, 1.0, curve: Curves.easeOut), ), ); _controller.forward(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { return Opacity( opacity: _opacityAnimation.value, child: Container( width: _sizeAnimation.value, height: _sizeAnimation.value, color: Colors.blue, ), ); }, ); } }
Always dispose your AnimationController to free resources.
Use AnimatedBuilder to rebuild only the parts that need animation updates.
Staggered animations make your UI feel more natural and less sudden.
Staggered animations run multiple animations one after another with delays.
Use Interval to control when each animation runs inside the total duration.
They help create smooth, engaging user experiences.
Practice
Solution
Step 1: Understand staggered animation concept
Staggered animations run animations sequentially with delays between them.Step 2: Compare options with concept
Only To run multiple animations one after another with delays describes running animations one after another with delays.Final Answer:
To run multiple animations one after another with delays -> Option AQuick Check:
Staggered animations = sequential with delays [OK]
- Thinking staggered means all animations run together
- Confusing staggered with stopping animations
- Assuming staggered animations create static UI
Solution
Step 1: Identify timing control in staggered animations
TheIntervalclass defines when each animation runs inside the total duration.Step 2: Match classes with their roles
Tween defines value changes, AnimationController controls animation progress, AnimatedBuilder rebuilds UI. Only Interval controls timing segments.Final Answer:
Interval -> Option CQuick Check:
Interval controls animation timing [OK]
- Confusing Tween with timing control
- Using AnimationController for timing intervals
- Thinking AnimatedBuilder controls timing
final animation1 = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: controller,
curve: Interval(0.0, 0.5),
),
);
final animation2 = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: controller,
curve: Interval(0.5, 1.0),
),
);Solution
Step 1: Understand Interval values and total duration
Interval(0.5, 1.0) means the animation starts at 50% of total duration.Step 2: Calculate start time
50% of 4 seconds = 0.5 * 4 = 2 seconds.Final Answer:
2 seconds -> Option DQuick Check:
Interval start 0.5 x 4s = 2s [OK]
- Using Interval end value as start time
- Confusing percentage with seconds directly
- Ignoring total duration in calculation
final animation1 = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: controller,
curve: Interval(0.6, 0.4),
),
);Solution
Step 1: Check Interval parameters
Interval requires start value less than end value. Here start=0.6, end=0.4 which is invalid.Step 2: Verify other parts
Tween values are valid, AnimationController is parent, CurvedAnimation usage is correct.Final Answer:
Interval start value is greater than end value -> Option BQuick Check:
Interval start must be less than end [OK]
- Swapping Interval start and end values
- Assuming Tween values cause error
- Missing AnimationController parent
Solution
Step 1: Divide total duration into three equal parts
Each animation lasts 1 second, total duration is 3 seconds, so each part is 1/3 = 0.33 (approx).Step 2: Calculate Interval for third animation
Third animation starts after first two: start = 2 x 0.33 = 0.66, end = 1.0 (full duration).Final Answer:
Interval(0.66, 1.0) -> Option AQuick Check:
Third animation Interval = 0.66 to 1.0 [OK]
- Using overlapping intervals
- Starting third animation too early
- Not dividing total duration evenly
Ready to prove it?
Pass the test and this pattern moves unknown
