I have looked at Staggered animations for chaining animations but there they use one animation for one widget's properties, e.g. a opacity animation is controlling the fade in, but what if I want to first fade in and then later fade out that same widget? I mean I already have created the fade in animation and that is used for the widget opacity value like this:
_opacityDontWorry = Tween(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(parent: _animationController, curve: Interval(0.0, 0.75, curve: Curves.easeIn)),
);
so those two are now bound together like this:
Opacity(
opacity: _opacityDontWorry.value,
child: Text("Don't worry"),
)
This work just fine and my Opacity get faded in, but after it is faded in I would like it to fade out after a short pause, but how can I do this? Do I create a new Tween and overwrite the _opacityDontWorry with that, or? Am I even on the right path here, how do I chain multiple animations that alter the same properties on a widget?
Thank you
Søren
May be this is a late answer. But a TweenSequence is the right class for animating the same attribute(s) mutations one after another. Docs reference.
You can use addStatusListener
on your Animation
. Check when the animation is completed and then call reverse()
on your AnimationController
.
If you want to, you can call reverse()
inside a Future.delayed()
for making a pause.
I've made this example for you:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
AnimationController _animationController;
Animation _opacityDontWorry;
@override
void initState() {
super.initState();
_animationController = AnimationController(duration: Duration(seconds: 1), vsync: this);
_opacityDontWorry = Tween(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(parent: _animationController, curve: Curves.easeIn),
)..addStatusListener((status) {
if (status == AnimationStatus.completed) {
Future.delayed(Duration(seconds: 3), () {
_animationController.reverse();
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton.extended(
label: Text('Animate'),
onPressed: () => _animationController.forward(),
),
body: Center(
child: AnimatedBuilder(
animation: _opacityDontWorry,
builder: (context, widget) {
return Opacity(
opacity: _opacityDontWorry.value,
child: Text("Don't worry"),
);
},
),
),
);
}
}
UPDATE
In case you need to play this animation, and call another one after that, you can extract the opacity value to a variable. Then update that value from as many consecutive animations as you need.
_firstAnimation = Tween(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(parent: _animationController, curve: Interval(0.0, 0.20, curve: Curves.easeIn)),
)..addListener(() {
setState(() => _opacity = _firstAnimation.value);
});
// Leave an interval pause if you need
_secondAnimation = Tween(
begin: 1.0,
end: 0.0,
).animate(
CurvedAnimation(parent: _animationController, curve: Interval(0.40, 0.60, curve: Curves.easeIn)),
)..addListener(() {
setState(() => _opacity = _secondAnimation.value);
});
In your widget's opacity property, instead of using _firstAnimation.value
use _opacity
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With