How to chain multiple controller/animation?
The trick is that you can create your own tween.
In short, what you want is a smooth curve that goes from 0 to 1 and then 1 to 0 smoothly. Which you can assimilate to a (sin(t * 2 * PI) + 1) / 2
where 0 <= t <= 1And then delay that curve for each cicles.
class TestTween extends Tween<double> { final double delay; TestTween({double begin, double end, this.delay}) : super(begin: begin, end: end); @override double lerp(double t) { return super.lerp((sin((t - delay) * 2 * PI) + 1) / 2); }}
Which allows to do
_controller = new AnimationController( vsync: this, duration: const Duration(seconds: 2),)..repeat();
instead of having to add an animation listener and reverse the animation.
The end result is
class CircleLoader extends StatefulWidget { @override _CircleLoaderState createState() => new _CircleLoaderState();}class _CircleLoaderState extends State<CircleLoader> with SingleTickerProviderStateMixin { AnimationController _controller; @override initState() { super.initState(); _controller = new AnimationController( vsync: this, duration: const Duration(seconds: 2), )..repeat(); } @override dispose() { _controller.dispose(); super.dispose(); } buildCircle(double delay) { return new ScaleTransition( scale: new TestTween(begin: .85, end: 1.5, delay: delay) .animate(_controller), child: new Container( height: 10.0, width: 10.0, decoration: new BoxDecoration( shape: BoxShape.circle, color: Colors.grey[300], ), ), ); } @override Widget build(BuildContext context) { return new Center( child: new Container( width: 100.0, height: 50.0, color: Colors.grey, child: new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ buildCircle(.0), buildCircle(.2), buildCircle(.4), ], ), ), ); }}class TestTween extends Tween<double> { final double delay; TestTween({double begin, double end, this.delay}) : super(begin: begin, end: end); @override double lerp(double t) { return super.lerp((sin((t - delay) * 2 * PI) + 1) / 2); }}