首页 > 解决方案 > 具有渐变背景颜色的动画容器

问题描述

如何从下到上更改容器的背景颜色?当我使用渐变时,我不喜欢这种效果。我构建了第二个容器,但它不是动态的。

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

我想要这种过渡,一遍又一遍地改变两个容器的颜色。如果状态发生变化,请进行转换,并在下一次迭代中更改颜色并再次播放。这是要模拟的动画。 视频动画

知道怎么做吗?

标签: flutterdartflutter-animation

解决方案


有类似ColorTween类的东西(https://api.flutter.dev/flutter/animation/ColorTween-class.html

你可以谷歌一些教程如何做到这一点,有很多。

更新

如果您想将一个容器与另一个容器悬停,然后及时重新打开它,我会将两者都Containers放入Stack widget并将其中一个的初始高度设置Containers为 0,并且只是设置动画高度。

更新 2

为了能够控制动画,您应该使用AnimationController并且可以忘记使用AnimatedContainer.

当我尝试如何重置AnimatedContainer时,有一些技巧可以做到这一点。关键是设置回调onEnd和内部将持续时间更改为1 milisecond,恢复_progress到初始值和setState,在再次开始动画之前,您需要设置适当的持续时间。

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

更新 3

为了能够循环它,您必须使用异步函数等到恢复到 A 点结束

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

这一切看起来有点棘手/肮脏,所以也许值得学习使用AnimationController和/或TweenAnimationBuilder


推荐阅读