Flutter:在 2 个 LinearGradients 之间淡入淡出

Flutter: fade between 2 LinearGradients

我想在按下按钮时将 LinearGradient 淡化为具有不同颜色的不同 LinearGradient,例如来自

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],
    ],
  )),
),

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],
    ],
  )),
),

我该怎么做?

最简单的解决方案是为按钮分配某种状态,使 Container 成为 AnimatedContainer 并向装饰参数添加条件。类似于我为这个问题创建的 class 。在其中,我将停止点和颜色列表设置为常量,这也使您的渐变也保持不变。然后你传递一个 "text" 参数,然后你可以选择有一个 onPressed 回调,它会告诉你它的状态是什么。我将其设为 class 以避免让整个父窗口小部件调用 setState 并给出常量以举例说明良好做法。尽量避免将这些东西放在构建方法中。

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
          ),
        ),
      ),
    );
  }
}

您可以使用 AnimatedContainer 来实现。

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],
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}