Reputation: 91
How can I change the background color of a container from bottom to top? When I use gradients, I don't like the effect. I build a second container, but it's not dynamic.
class MyCustomContainer extends StatefulWidget {
final Color backgroundColor;
final Color progressColor;
final double progress;
final double size;
const MyCustomContainer({
Key key,
this.backgroundColor = Colors.grey,
this.progressColor = Colors.red,
@required this.progress,
@required this.size,
}) : super(key: key);
@override
_MyCustomContainerState createState() => _MyCustomContainerState();
}
class _MyCustomContainerState extends State<MyCustomContainer> {
double _progress;
@override
void initState() {
super.initState();
_progress = widget.progress;
}
onPaint() {
setState(() {
if (_progress == 0) {
_progress = 1;
} else {
_progress = 0;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
height: widget.size,
width: widget.size,
child: Stack(
children: [
Container(
color: widget.backgroundColor,
child: Column(
children: [
Container(
height: widget.size * 0.3,
color: Colors.green,
),
Container(
height: widget.size * 0.7,
color: Colors.red,
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOutExpo,
height: widget.size * _progress,
child: Column(children: [
Container(
height: widget.size * 0.3,
color: Colors.red,
),
Container(
height: widget.size * 0.7,
color: Colors.green,
),
]),
),
),
Text('asdas'),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => onPaint(),
child: Icon(Icons.ac_unit),
),
);
}
}
I want that transition, over an over again changing the colors of the two containers. If the states changes, do the transition and in the next iteration, change colors and play again. This is the animation to emulate. Video animation
Any idea how?
Upvotes: 3
Views: 3010
Reputation: 1431
There is something like ColorTween
class ( https://api.flutter.dev/flutter/animation/ColorTween-class.html )
You can google some tutorial how to do that, there is plenty of it.
Update
In case that you want to hover one container with another and then in time reaviling it I would put both Containers
into the Stack widget
and set initial height of one of Containers
to 0 and just animate height.
Update 2
To be able to control animation you should use AnimationController
and you could forget about using AnimatedContainer
.
As I experimented in the ways how to reset AnimatedContainer
, there is some trick to do that. The key is to set callback onEnd
and inside to change duration to 1 milisecond
, restore _progress
to initial value and setState
, Before starting animation again you will need to set proper duration.
void initState() {
super.initState();
_progress = 0;
}
onPaint() {
setState(() {
dynamicDuration = Duration(milliseconds: 2000);
if (_progress == 1) {
_progress = 0;
} else {
_progress = 1;
}
});
}
void resetAnim(){
setState((){
dynamicDuration = Duration(milliseconds: 1);
_progress = 0;
});
}
Update 3
to be able to loop it you would have to use async function to wait till restoration to point A has ended
void resetAnim() async {
setState((){
dynamicDuration = Duration(milliseconds: 1);
_progress = 0;
});
await new Future.delayed(const Duration(milliseconds : 50));
setState(() {
dynamicDuration = Duration(milliseconds: 2000);
_progress = 1;
});
It all looks kinda tricky/dirty so maybe it would be worth learning to use AnimationController
and/or TweenAnimationBuilder
Upvotes: 1