Reputation: 2896
I know how to change the background but I need it to be changing continuously.
How do I achieve this?
Upvotes: 13
Views: 13384
Reputation: 1235
Another option is to use ColorTween.
Here is a widget that can be placed as a background and will continuously animate nicely between two colors which are passed in as arguments.
import 'package:flutter/material.dart';
class AnimatedColorBackground extends StatefulWidget {
const AnimatedColorBackground(
{Key? key, required this.primaryColor, required this.secondaryColor})
: super(key: key);
final Color primaryColor;
final Color secondaryColor;
@override
State<AnimatedColorBackground> createState() =>
_AnimatedColorBackgroundState();
}
class _AnimatedColorBackgroundState extends State<AnimatedColorBackground>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Color?> _colorTween;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(
seconds: 10,
),
vsync: this);
_colorTween =
ColorTween(begin: widget.primaryColor, end: widget.secondaryColor)
.animate(
CurvedAnimation(parent: _controller, curve: Curves.easeOutSine))
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.reverse();
}
if (status == AnimationStatus.dismissed) {
_controller.forward();
}
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: _colorTween.value,
);
}
}
Upvotes: 0
Reputation: 9
I would instead initiate the transition in initState method as such:
@override
void initState() {
super.initState();
Future.delayed(const Duration(milliseconds: 500), () {
setState(() {
bottomColor = Colors.blue;
});
});
}
DISCLAIMER: this answer was inspired by the two above
Upvotes: 0
Reputation: 452
To auto animate the gradient just add this block of code in @override Widget build(BuildContext context) {}
method of SeriForte's code.
Future.delayed(const Duration(milliseconds: 10), () {
setState(() {
bottomColor = Colors.blue;
});
});
Upvotes: 11
Reputation: 700
you could use an AnimatedContainer
and reset the target color when the animation is over.
For a smooth Transition, I suggest a List of Colors you can loop over, you can do the same with the Alignment.
Example:
Source Code for the Example:
import 'package:flutter/material.dart';
class AnimatedGradient extends StatefulWidget {
@override
_AnimatedGradientState createState() => _AnimatedGradientState();
}
class _AnimatedGradientState extends State<AnimatedGradient> {
List<Color> colorList = [
Colors.red,
Colors.blue,
Colors.green,
Colors.yellow
];
List<Alignment> alignmentList = [
Alignment.bottomLeft,
Alignment.bottomRight,
Alignment.topRight,
Alignment.topLeft,
];
int index = 0;
Color bottomColor = Colors.red;
Color topColor = Colors.yellow;
Alignment begin = Alignment.bottomLeft;
Alignment end = Alignment.topRight;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
AnimatedContainer(
duration: Duration(seconds: 2),
onEnd: () {
setState(() {
index = index + 1;
// animate the color
bottomColor = colorList[index % colorList.length];
topColor = colorList[(index + 1) % colorList.length];
//// animate the alignment
// begin = alignmentList[index % alignmentList.length];
// end = alignmentList[(index + 2) % alignmentList.length];
});
},
decoration: BoxDecoration(
gradient: LinearGradient(
begin: begin, end: end, colors: [bottomColor, topColor])),
),
Positioned.fill(
child: IconButton(
icon: Icon(Icons.play_arrow),
onPressed: () {
setState(() {
bottomColor = Colors.blue;
});
},
),
)
],
));
}
}
Upvotes: 35