Staggered Animation in Flutter, “Staggered” means ‘moving in an unsteadily way whereas Staggered Animation is an animation that consists of sequential animations.
In this, all the animations are controlled with the help of a single Animation Controller.
This Animation Controller will handle multiple Animation objects in order to perform animations in order.
In order to set up the animation, we will have to follow a few steps:-
- Firstly, create an AnimationController that will manage all the animations.
- Now, create a Tween for each property being animated.
- The Tween defines a range of values.
- Tween’s animation method requires the parent controller and produces an Animation for that property.
- At last, specify the interval on the Animation’s Curve property.
You may also check our Flutter app development company page
Firstly, We will have to create Tween animation for all the properties which we want to animate, like this
1 2 3 4 5 6 |
height = Tween<double>(begin: 0, end: 150).animate( CurvedAnimation( parent: controller, curve:const Interval(0, 0.3, curve: Curves.easeIn), ), ) |
Secondly, we have created a StaggeredWidget, which represents the widget we are animating.
In this, we are animating three properties of a container: height, width & opacity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
class StaggeredWidget extends StatelessWidget { final AnimationController controller; final Animation<double> opacity; final Animation<double> height; final Animation<double> width; StaggeredWidget({required this.controller}) : height = Tween<double>(begin: 0, end: 150).animate( CurvedAnimation( parent: controller, curve:const Interval(0, 0.3, curve: Curves.easeIn), ), ), width = Tween<double>(begin: 0, end: 150).animate(CurvedAnimation( parent: controller, curve: const Interval(0, 0.3, curve: Curves.easeIn), )), opacity = Tween<double>(begin: 0, end: 1).animate( CurvedAnimation( parent: controller, curve: const Interval(0.3, 0.6, curve: Curves.fastOutSlowIn), ), ); Widget animatedWidget(BuildContext context, Widget? child) { return Container( padding: EdgeInsets.all(20.0), alignment: Alignment.bottomCenter, child: Center( child: Opacity( opacity: opacity.value, child: Container( width: width.value, height: height.value, decoration: BoxDecoration( color: Colors.red, border: Border.all( color: Colors.grey, width: 3.0, ), borderRadius: BorderRadius.all(Radius.circular(4.0)), ), ), ), ), ); } @override Widget build(BuildContext context) { return AnimatedBuilder( builder: animatedWidget, animation: controller, ); } } |
The AnimatedBuilder builds a widget and configures it by using the current values from the Tween.
Most Importantly, it takes a parent controller and a builder widget for animation.
Final Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.lightGreen, ), home: StaggerDemo()); } } class StaggerDemo extends StatefulWidget { @override _StaggerDemoState createState() => _StaggerDemoState(); } class _StaggerDemoState extends State<StaggerDemo> with TickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this); _controller.forward(); } Future<void> _playAnimation() async { try { await _controller.forward().orCancel; await _controller.reverse().orCancel; } on TickerCanceled {} } @override Widget build(BuildContext context) { timeDilation = 4.0; return Scaffold( appBar: AppBar( title: const Text('Staggered Animation'), ), body: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { _playAnimation(); }, child: Center( child: Container( width: 300.0, height: 300.0, decoration: BoxDecoration( color: Colors.lightGreen, border: Border.all( color: Colors.black.withOpacity(0.5), ), ), child: StaggeredWidget( controller: _controller, )), ), ), ); } @override void dispose() { _controller.dispose(); super.dispose(); } } class StaggeredWidget extends StatelessWidget { final AnimationController controller; final Animation<double> opacity; final Animation<double> height; final Animation<double> width; StaggeredWidget({required this.controller}) : height = Tween<double>(begin: 0, end: 150).animate( CurvedAnimation( parent: controller, curve:const Interval(0, 0.3, curve: Curves.easeIn), ), ), width = Tween<double>(begin: 0, end: 150).animate(CurvedAnimation( parent: controller, curve: const Interval(0, 0.3, curve: Curves.easeIn), )), opacity = Tween<double>(begin: 0, end: 1).animate( CurvedAnimation( parent: controller, curve: const Interval(0.3, 0.6, curve: Curves.fastOutSlowIn), ), ); Widget animatedWidget(BuildContext context, Widget? child) { return Container( padding: EdgeInsets.all(20.0), alignment: Alignment.bottomCenter, child: Center( child: Opacity( opacity: opacity.value, child: Container( width: width.value, height: height.value, decoration: BoxDecoration( color: Colors.red, border: Border.all( color: Colors.grey, width: 3.0, ), borderRadius: BorderRadius.all(Radius.circular(4.0)), ), ), ), ), ); } @override Widget build(BuildContext context) { return AnimatedBuilder( builder: animatedWidget, animation: controller, ); } } |
Output
At last, the output of the code is-
Staggered Animation In Flutter
Conclusion
In this blog, we have discussed Staggered Animation in Flutter.
I hope it will help you out in understanding.
Thanks for reading!!
References
https://docs.flutter.dev/development/ui/animations/staggered-animations