代码之家  ›  专栏  ›  技术社区  ›  Peter Weyand

颤振动画未褪色(正在闪烁)

  •  0
  • Peter Weyand  · 技术社区  · 6 年前

    下面是关于的动画教程 flutter 在这里: https://flutter.io/tutorials/animation/#animationcontroller ,我正在尝试让图标在紫色和橙色之间淡入淡出。不幸的是,我所能做的就是得到一个图标 眨眼 这似乎很令人沮丧,因为这不是 ColorTween 类已定义。从文档中:

    我们建议您不要传递颜色。开始或结束时透明 如果想要淡入或淡出透明的效果。相反 首选空值。颜色。透明是指黑色透明,因此 将淡出或变成可能不需要的黑色。

    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();
      }
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Brian Armstrong    6 年前

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

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

    此回调将侦听动画的每个勾号,并将导致小部件重新渲染。由于您希望每个勾号都重新绘制此小部件的所有子项,因此这很有意义。如果您只想重画一些子对象,那么可能需要将它们包装在动画小部件中。

    您仍然需要删除 设置状态 的内部 addStatusListener 因为它对新的侦听器是多余的。