我正在关注flutter
这里的动画教程:https://flutter.io/tutorials/animation/#animationcontroller,我正试图让一个图标在紫色和橙色之间淡入淡出。不幸的是,我设法做的就是获得 blink 的图标,这似乎非常令人沮丧,因为这不是ColorTween
类的定义方式。来自文档:
我们建议您不要将Colors.transparent作为开头或结尾传递 如果你想要淡入或淡出透明效果。代替 喜欢null。 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();
}
}
答案 0 :(得分:2)
您需要创建一个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((){}));
此回调侦听动画的每个刻度并将导致窗口小部件重新呈现。由于你想重新绘制每个小部件的所有子节点,这是有道理的。如果你只想重绘一些孩子,你可能想把它们包装在AnimatedWidgets中。
您仍然希望删除setState
内的addStatusListener
,因为它对新侦听器来说是多余的。