我有一个简单的AnimatedWidget
与一个儿童小部件。
AnimatedContainer(
duration: Duration(milliseconds: 2000),
curve: Curves.bounceOut,
decoration: BoxDecoration(
color: Colors.purple,
),
child: FlutterLogo(
size: _boxSize,
),
),
其中_boxSize
的动画如下:
void _startAnimation() => setState(() {
_boxSize *= 1.7;
});
但是,AnimatedContainer
不适用于儿童小部件。您需要更改AnimatedContainer
的直接属性才能使动画生效。
这符合文档:
The [AnimatedContainer] will automatically animate between the old
and new values of properties when they change using the provided curve
and duration. Properties that are null are not animated.
Its child and descendants are not animated.
什么相当于AnimatedContainer
,它也可以为其孩子制作动画?
没有神奇的小部件可以简单地递归动画所有孩子。但我认为你想要的是一个隐式动画小部件。即。您更改窗口小部件的构造函数参数,并且当它更改时,它会从一个值动画到下一个值。
最简单的方法可能是ImplicitlyAnimatedWidget
和AnimatedWidgetBaseState
。因此,为您的示例设置boxSize
属性的动画,这可能如下所示:
class AnimatedFlutterLogo extends ImplicitlyAnimatedWidget {
const AnimatedFlutterLogo({Key key, @required this.boxSize, @required Duration duration})
: super(key: key, duration: duration);
final double boxSize;
@override
ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() => _AnimatedFlutterLogoState();
}
class _AnimatedFlutterLogoState extends AnimatedWidgetBaseState<AnimatedFlutterLogo> {
Tween<double> _boxSize;
@override
void forEachTween(visitor) {
_boxSize = visitor(_boxSize, widget.boxSize, (dynamic value) => Tween<double>(begin: value));
}
@override
Widget build(BuildContext context) {
return Container(
child: FlutterLogo(
size: _boxSize?.evaluate(animation),
),
);
}
}
这是非常简洁的,唯一真正的样板基本上是forEachTween(visitor)
方法,它必须为你想要动画的所有属性创建Tween
对象。