【问题标题】:Flutter Animation Not Fading (It's Blinking)Flutter 动画不褪色(闪烁)
【发布时间】:2018-03-07 16:22:55
【问题描述】:

我正在关注flutter 上的动画教程:https://flutter.io/tutorials/animation/#animationcontroller,我正在尝试让图标在紫色和橙色之间淡入淡出。不幸的是,我所做的只是得到一个 blink 的图标,这似乎非常令人沮丧,因为这不是 ColorTween 类的定义方式。来自文档:

我们建议您不要将 Colors.transparent 作为开始或结束传递 如果你想要淡入或淡出透明的效果。反而 更喜欢空。 Colors.transparent 指的是黑色透明,因此 会淡出或变成黑色,这可能是不需要的。

https://docs.flutter.io/flutter/animation/ColorTween/ColorTween.html

我推断这意味着褪色是“开箱即用”的。但是,我也用CurvedAnimation 类测试过它,它仍然闪烁。我还用一个文本框进行了测试,认为它正在加载一个图标的事实可能会搞砸它。但是,文本值也会在橙色和紫色之间闪烁。在下面的代码中,我让它反转动画 - 我也尝试将其撕掉,但这不会影响闪烁。我在想这可能与我设置状态的方式有关某些,但我不确定。

我试图基于以下代码的主要教程示例来自这里:https://raw.githubusercontent.com/flutter/website/master/_includes/code/animation/animate3/main.dart

请参阅下面的代码以了解我的实现。任何建议将不胜感激。

class CloudAnimation1 extends StatefulWidget {

  @override
  CloudAnimation1State createState() => new CloudAnimation1State();
}

class CloudAnimation1State extends State<CloudAnimation1> with SingleTickerProviderStateMixin {

  Animation<Color> animation;
  AnimationController controller;

  initState() {
    super.initState();
    controller = new AnimationController(
        duration: const Duration(milliseconds: 1000), vsync: this);
    final Animation curve = new CurvedAnimation(parent: controller, curve: Curves.easeOut);
    animation = new ColorTween(begin: Colors.orange, end: Colors.purple).animate(curve);


    animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        controller.forward();
      }
      setState(() {
        // the animation object’s value is the changed state
      });
    });
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
      child: new Row(
        children: <Widget>[
          new Text("hello there sailor",
              style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 25.0, color: animation.value)),
          new Icon(FontAwesomeIcons.cloud, color: animation.value, size: 40.0)
        ],
      ),
    );
  }

  dispose() {
    controller.dispose();
    super.dispose();
  }

}

【问题讨论】:

    标签: android ios animation mobile flutter


    【解决方案1】:

    您需要创建一个 AnimatedIcon 来实际处理动画状态。

    class AnimatedIcon extends AnimatedWidget {
      final IconData icon;
    
      AnimatedIcon({Key key, Animation<Color> animation, this.icon})
          :super(key: key, listenable: animation);
    
      @override
      Widget build(BuildContext context) {
        final Animation<Color> animation = listenable;
        return new Row(
            children: <Widget>[
              new Text("hello there sailor",
                  style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 25.0, color: animation.value)),
              new Icon(icon, color: animation.value, size: 40.0)
            ],
          );
      }
    }
    

    然后您可以将CloudAnimation1State 中的构建替换为

    @override
    Widget build(BuildContext context) {
      return new Container(
        child: new AnimatedIcon(
          animation: animation,
          icon: Icons.ac_unit,
        ),
      );
    }
    

    然后移除动画状态监听器中的空setState


    或者...

    之所以会闪烁是因为animation.addStatusListener 仅在动画状态发生变化时调用,而不是在每次滴答时调用。 AnimatedWidget 只是包装和抽象监听滴答声。

    将以下代码添加到您的initState

    animation.addListener(() => setState((){}));
    

    这个回调监听动画的每一个tick,并会导致小部件重新渲染。由于您想在每个刻度上重绘此小部件的所有子级,因此这是有道理的。如果您只想重绘一些孩子,您可能希望将它们包装在 AnimatedWidgets 中。

    您仍然需要删除 addStatusListener 内部的 setState,因为它对于新侦听器来说是多余的。

    【讨论】:

    • 不过,您可能不应该将小部件命名为 AnimatedIcon,因为这已经在 Flutter 命名空间中了。
    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 2014-08-02
    • 2011-12-02
    • 2012-03-12
    相关资源
    最近更新 更多