Flutter 组件集录 | TweenAnimationBuilder 补间动画构造器
当你想要让一个组件在出现时就具有动画效果,又懒得使用动画控制器,还懒得触发属性更新使用隐式动画。那么 TweenAnimationBuilder 将可以很好地帮助你完成动画效果。该组件已收录到 FlutterUnit,感兴趣的朋友可以参阅。
1. 一个案例简单了解 TweenAnimationBuilder
下面案例中,组件在刚出现时,就会伴随背景由 蓝 到 红
的渐变动画。这里没有使用动画控制器来主动修改颜色属性;也没有通过隐式动画通过修改属性重新构建触发动画。
TweenAnimationBuilder 组件在构造时通过 tween
字段,指定补间过渡的首尾属性;在 builder 回调中可以感知补间动画当前帧对应的值。根据该值就可以控制每个属性的动画效果。比如下面在 builder 中根据 value 值设置 Container 的颜色:
import 'package:flutter/material.dart';
class TweenAnimationBuilderDemo extends StatelessWidget {
const TweenAnimationBuilderDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder(
tween: ColorTween(begin: Colors.blue, end: Colors.red),
duration: const Duration(milliseconds: 800),
builder: (BuildContext context, Color? color, Widget? child) {
return Container(
width: 40,
height: 40,
child: child,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(5)
),
);
},
child: const Icon( Icons.android_outlined, color: Colors.white),
);
}
}
2. TweenAnimationBuilder 也是一种隐式动画
隐式动画的特点是不需要用开发者主动创建动画控制器,只需要修改属性,重新构建就可以触发动画变换。我们可以控制 tween 的起止值,达到动态控制动画的效果。比如下面案例中,每次点击时背景都会动画变换到另一种颜色,依次是红、橙、黄、绿、蓝、靛、紫 :
由于需要修改起止的颜色值,进行重新构建,所以这里使用了 StatefulWidget
其中定义了:
- 支持的颜色列表
colors
, - 当前的激活颜色索引
_activeIndex
, - 根据上面两个数据可以计算出补间颜色的起始 begin 和结尾 end 颜色
class _TweenAnimationBuilderDemoState extends State<TweenAnimationBuilderDemo> {
List<Color> get colors => const [
Colors.red,
Colors.orange,
Colors.yellow,
Colors.green,
Colors.blue,
Colors.indigo,
Colors.purple
];
int _activeIndex = 0;
Color get begin => colors[_activeIndex % colors.length];
Color get end => colors[(_activeIndex + 1) % colors.length];
在 TweenAnimationBuilder 构造时取用 begin 和 end 构建新的颜色补间即可,点击时触发 nextColor
更新到写一个颜色索引。
void nextColor(){
_activeIndex++;
setState(() {});
}
这样就完成了上面的效果,总得来说 TweenAnimationBuilder 和常规的隐式动画用法类似,只不过它的属性是个 Tween 补间对象。而且可以在组件初始化时就立刻执行补间动画。
2. TweenAnimationBuilder 源码简看
TweenAnimationBuilder 继承自 ImplicitlyAnimatedWidget ,说明它的底层确实是补间动画的一套东西,
TweenAnimationBuilder 可以在初始化时执行动画的原因,可以在源码中窥见本质。如下所示,在初始化状态时,如果补间对象的起止值不同,就会触发动画控制器的 forward
方法执行动画:
而动画控制器封装在父类 ImplicitlyAnimatedWidgetState
中,
当外界触发更新时,ImplicitlyAnimatedWidgetState 中的 didUpdateWidget 会触发,其中执行 forEachTween
的抽象方法,该方法将有子类实现,处理补间的具体更新逻辑:
从子类 _TweenAnimationBuilderState
的实现中可以看到,它会基于新补间参数的结尾和当前补间的值形成一个新的补间对象,继续进行动画。这也就是 TweenAnimationBuilder 在补间连续变化时,可以保持连贯性的秘密。
希望等你想做动画效果时 TweenAnimationBuilder 可以帮助到你,比如菜单展开时的动画,用 TweenAnimationBuilder 就很合适。那本文就到这里,更多的组件介绍分享,敬请期待 ~