SizeTransition 用裁剪,摆放 child 的方式让 child 产生动画效果。
本来 SizeTransition 继承自 AnimatedWidget 没什么好讲的,掌握 AnimatedWidget 就足够了, 但是他产生动画的方式有点出乎意料。不是像直觉那样,改变 child 的 width,height。他是通过 clip + align 做动画,这样组合起来,可以产生的动画效果一下子丰富起来。如果不事先有个印象,知道 SizeTransition 能做出怎样的效果,用的时候,可能不一定能想起他来。
源码分析
Widget build(BuildContext context) {
final AlignmentDirectional alignment;
if (axis == Axis.vertical) {
alignment = AlignmentDirectional(-1.0, axisAlignment);
} else {
alignment = AlignmentDirectional(axisAlignment, -1.0);
}
return ClipRect(
child: Align(
alignment: alignment,
heightFactor: axis == Axis.vertical ? math.max(sizeFactor.value, 0.0) : null,
widthFactor: axis == Axis.horizontal ? math.max(sizeFactor.value, 0.0) : null,
child: child,
),
);
}
由两个 widget 嵌套而成。 sizeFactor.value 从 0 到 1,Align 的大小由 0 到 child size。如果没有 ClipRect ,在我们看来,child size 在视觉上 不会发生变化。Align size 虽然变小了,但却不能把 child 溢出的部分 clip 。外面加上 ClipRect 后,默认会把 child 溢出的部分 clip,我们就能看到 child size 的变化了。
使用 SizeTransition
最重要的是要对 SizeTransition 的效果有个印象,以便后面需要的时候能想起来。
Container(
width: 100,
height: 100,
alignment: Alignment.topLeft,
child: SizeTransition(
axis:Axis.vertical,
axisAlignment: -1,
sizeFactor: controller,
child: FlutterLogo(
size: 100,)));
- 父级 alignment: Alignment.topLeft
- SizeTransition axisAlignment: -1,内部转换为 AlignmentDirectional(-1.0, -1.0)
使用 SizeTransition 的时候,需要注意确定好 alignment。比如本例,SizeTransition 左上角对齐,child 也是左上角对齐。child size 变化的时候,就会有从上向下展示的效果。
其实也很简单,只要保证 SizeTransition 父级的对齐和 child 的对齐方式一致就可以,比如由中间开始向外扩展的效果。
Container(
width: 100,
height: 100,
alignment: Alignment.center,
child: SizeTransition(
axis:Axis.vertical,
axisAlignment: 0,
sizeFactor: controller,
child: FlutterLogo(
size: 100,
)));
- 父级 alignment: Alignment.center
- SizeTransition axisAlignment: 0,内部转换为 AlignmentDirectional(0.0, 0.0)
还可以从下向上展示。
Container(
width: 100,
height: 100,
alignment: Alignment.bottomLeft,
child: SizeTransition(
axis:Axis.vertical,
axisAlignment: 1,
sizeFactor: controller,
child: FlutterLogo(
size: 100,
)));
- 父级 alignment: Alignment.bottomLeft
- SizeTransition axisAlignment: 1,内部转换为 AlignmentDirectional(-1.0, 1.0)
除了这三种,还有水平的三种,一共六种动画展示方式。只要保证 SizeTransition 在父级的对齐和 SizeTransition 的对齐方式一致就可以,就可以达成相应的效果。