Reputation: 2166
I would like to fade a LinearGradient into a different LinearGradient with different colors when I press a button, e.g. from
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
stops: [0.1, 0.5, 0.7, 0.9],
colors: [
Colors.blue[700],
Colors.blue[600],
Colors.blue[500],
Colors.blue[300],
],
)),
),
to
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
stops: [0.1, 0.5, 0.7, 0.9],
colors: [
Colors.red[700], // different color
Colors.red[600],
Colors.red[500],
Colors.red[300],
],
)),
),
How can I do this?
Upvotes: 4
Views: 2486
Reputation: 2304
The simplest solution would be to assign some kind of state for the button, make the Container an AnimatedContainer and add a conditional to the decoration parameter. Something like the class I created for this question. In it I've made your stops and color lists constants, which allow your gradients to be constant as well. Then you pass a "text" argument and then you optionally have an onPressed callback that will tell you what its state is. I made this a class so to avoid letting the setState get called for the entire parent widget and the constants were given to exemplify good practices. Try to avoid placing these kinds of things in build methods.
const _stops = [0.1, 0.5, 0.7, 0.9];
const _redColors = [
Color(0xFFD32F2F), // different color
Color(0xFFE53935),
Color(0xFFF44336),
Color(0xFFE57373),
];
const _blueColors = [
Color(0xFF1976D2),
Color(0xFF1E88E5),
Color(0xFF2196F3),
Color(0xFF64B5F6),
];
const _red = const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
stops: _stops,
colors: _redColors,
)
);
const _blue = const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
stops: _stops,
colors: _blueColors,
)
);
class RedBlueButton extends StatefulWidget {
final Function(bool) onPressed;
final String text;
final String submittedText;
const RedBlueButton({Key key, this.onPressed, this.text, this.submittedText}) : super(key: key);
@override
_RedBlueButtonState createState() => _RedBlueButtonState();
}
class _RedBlueButtonState extends State<RedBlueButton> {
bool pressed = false;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: (){
setState(() {
pressed = !pressed;
if(widget.onPressed != null)
widget.onPressed(pressed);
});
},
child: AnimatedContainer(
duration: kThemeChangeDuration,
decoration: pressed ? _red : _blue,
alignment: Alignment.center,
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5
),
child: Text(
pressed ? widget.text ?? 'submit' : widget.submittedText ?? 'sent',
style: TextStyle(
color: Colors.white
),
),
),
);
}
}
Upvotes: 0
Reputation: 27147
you can use AnimatedContainer to do so.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Color> change = [Colors.blue[700],Colors.blue[600],Colors.blue[500],Colors.blue[300]];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
),
backgroundColor: Colors.transparent,
body: InkWell(
onTap: (){
change[0] = Colors.red[700];
change[1] = Colors.red[600];
change[2] = Colors.red[500];
change[3] = Colors.red[300];
},
child: AnimatedContainer(
child: Center(child: new Text("hello")),
duration: Duration(seconds: 5),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
stops: [0.1, 0.5, 0.7, 0.9],
colors: [
change[0],
change[1],
change[2],
change[3],
],
),
),
),
),
),
);
}
}
Upvotes: 5