JakesMD
JakesMD

Reputation: 2166

Flutter: fade between 2 LinearGradients

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

Answers (2)

Adrian Murray
Adrian Murray

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

Viren V Varasadiya
Viren V Varasadiya

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

Related Questions