1、AnimatedContainer
在一段时间内逐渐改变属性值的 Container。
为 null 的属性,以及 Container 的子孙不会发生动画。
AnimatedContainer 使用内部的 AnimationController,在 Container 的属性中产生简单的、隐式动画。
如果要产生更复杂的动画,可以使用 AnimatedWidget 的子类(例如 DecoratedBoxTransition),或者自己声明的 AnimationController。
2、AnimatedCrossFade
在 widget 的两个 children 之间交叉淡入淡出,并在 children 的尺寸之间产生动画。
通过 crossFadeState 参数控制动画。firstCurve 和 secondCurve 表示两个 children 的不透明曲线。sizeCurve 表示在淡出 child 的尺寸和淡入 child 尺寸之间的动画曲线。
AnimatedCrossFade 用于淡入淡出一对相同宽度的 widgets。如果两个 children 的高度不同,动画会对其 children 的顶部边缘,并裁剪溢出的部分,也就是会裁剪底部。
使用不同的 crossFadeState 属性值重建 AnimatedCrossFade
时,将自动触发动画。
AnimatedCrossFade(
duration: const Duration(seconds: 3),
firstChild: const FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
crossFadeState: _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
)
3、Hero
标记 widget 的 child 为 hero animations 的候选人。
Hero animation: 使用
Navigator压入或弹出PageRoute时,会替换整个屏幕的内容。如果两个路由有共同的视觉特征,那么在路由过渡期间,可以告诉用户该特征从一个页面移动了另一个页面。过渡期间,hero widget在Navigator层之上“飞行”。默认情况下,飞行期间不会在旧路由和新路由上显示原来的位置。
发生导航时,每个路由的 Hero widgets 由 HeroController 确定。有相同 tag 的每一对 Hero widgets 都会触发 Hero animation。
一个路由不能包含多个相同 tag 的 Hero。
4、AnimatedBuilder
创建动画的通用 widget。
AnimatedBuilder 适用于在复杂的 build 函数中包含动画的 widgets。
对于没有额外状态的简单情况,考虑使用 AnimatedWidget。
class Spinner extends StatefulWidget {
@override
_SpinnerState createState() => _SpinnerState();
}
class _SpinnerState extends State<Spinner> with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 10),
vsync: this,
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
child: Container(width: 200.0, height: 200.0, color: Colors.green),
builder: (BuildContext context, Widget child) {
return Transform.rotate(
angle: _controller.value * 2.0 * math.pi,
child: child,
);
},
);
}
}
5、DecoratedBoxTransition
DecoratedBox 的动画版,让 Decoration 的不同属性产生动画。
6、FadeTransition
使 widget 的不透明度产生动画。
7、PositionedTransition
Positioned 的动画版,使用指定的 Animation<RelativeRect>,在动画的生命周期里,把 child 的位置从起点过渡到终点。
只有是 Stack 的 child 时才能工作。
8、RotationTransition
使 widget 的选择产生动画。
9、ScaleTransition
使 widget 的缩放产生动画。
10、SizeTransition
使自身的尺寸产生动画,并裁剪和对其它的 child。
SizeTransition 类似 ClipRect,根据 axis 的值,使它的宽度或高度产生动画。
11、SlideTransition
相对于 widget 的正常位置,让它的位置产生动画。
通过 Offset 相对于 child 的尺寸产生动画。例如,Offset 的 dx 值是 0.25,则会产生 child 四分之一宽度的水平位置动画。
12、AnimatedDefaultTextStyle
DefaultTextStyle 的动画版。当给定的样式改变时,在给定的周期内产生动画。
textAlign、softWrap、textOverflow 和 maxLines 属性不会产生动画,改变时立即生效。
13、AnimatedListState
在可滚动容器中 state的插入或移除项时产生动画。
14、AnimatedModalBarrier
阻止用户与 widget 后面的 widgets 交互,可以配置一个有动画的颜色值。
与 ModalBarrier 类似,AnimatedModalBarrier 接收一个有动画的 color,而不是单个颜色。
15、AnimatedOpacity
Opacity 的动画版,当给定的不透明度变化时,在给定周期内过渡 child 的不透明度。
这个动画很昂贵,因为需要把 child 绘制到一个中间缓存中。
class LogoFade extends StatefulWidget {
@override
createState() => LogoFadeState();
}
class LogoFadeState extends State<LogoFade> {
double opacityLevel = 1.0;
void _changeOpacity() {
setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedOpacity(
opacity: opacityLevel,
duration: Duration(seconds: 3),
child: FlutterLogo(),
),
RaisedButton(
child: Text('Fade Logo'),
onPressed: _changeOpacity,
),
],
);
}
}
参考:6、FadeTransition,该
widget的明确版,由调用者传入Animation,而不是使用内置的。
16、AnimatedPhysicalModel
PhysicalModel 的动画版,borderRadius 和 elevation 会产生动画,shap 不会产生动画。
如果设置了 animateColor 属性,则 color 也会产生动画;否则会颜色会立即改变。这可以让颜色单独产生动画(比如由 AnimatedTheme 驱动)。
17、AnimatedPositioned
Positioned 的动画版。
只有是 Stack 的 child 时才能工作。
如果 child 的 size 在动画过程会改变,则 AnimatedPositioned 是很好的选择。如果尺寸不变,只有 position 改变,则考虑使用 SlideTransition。
18、AnimatedSize
动画改变 child 尺寸的 widget。
19、AnimatedWidget
当给定的 Listenable 的值改变时,AnimatedWidget 会 rebuild。
AnimatedWidget 最常见的用法是与 Animation 对象配合,Animation 是 Listenable。但它也可以与任何 Listenable 配置,包括 ChangeNotifier 和 ValueNotifier。
AnimatedWidget 对无状态的 widget 最有用。只需要继承 AnimatedWidget,并实现 build 函数。
class Spinner extends StatefulWidget {
@override
_SpinnerState createState() => _SpinnerState();
}
class _SpinnerState extends State<Spinner> with TickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 10),
vsync: this,
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SpinningContainer(controller: _controller);
}
}
class SpinningContainer extends AnimatedWidget {
const SpinningContainer({Key key, AnimationController controller})
: super(key: key, listenable: controller);
Animation<double> get _progress => listenable;
@override
Widget build(BuildContext context) {
return Transform.rotate(
angle: _progress.value * 2.0 * math.pi,
child: Container(width: 200.0, height: 200.0, color: Colors.green),
);
}
}
20、AnimatedWidgetBaseState
具有隐式动画的 widget 的基类,需要在动画执行时 rebuild widget tree 。