Flutter 动画组件那么多,记不住不会用怎么办?我都给你整理好了,收藏吧!
前言
Flutter 自带的基础动画组件称之为隐式动画组件,小小统计了一下,会有几十个那么多,包括通用的动画构建类、特定的动画效果类以及封装好的动画组件。这么多,好处是想用的基本都有,不好的地方是记不住,找起来也不太方便。本篇特地整理了 Flutter 的隐式动画组件,方便各位 Flutter 爱好者(搬砖者)随时查看和使用。
AnimatedWidget
const AnimatedWidget({
Key? key,
required this.listenable,
})
Animation
AnimatedBuilder
const AnimatedBuilder({
Key? key,
required Listenable animation,
required this.builder,
this.child,
})
AnimatedContainer
AnimatedContainer({
Key? key,
this.alignment,
this.padding,
Color? color,
Decoration? decoration,
this.foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
this.margin,
this.transform,
this.transformAlignment,
this.child,
this.clipBehavior = Clip.none,
Curve curve = Curves.linear,
required Duration duration,
VoidCallback? onEnd,
})
AnimatedPositioned
const AnimatedPositioned({
Key? key,
required this.child,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
Curve curve = Curves.linear,
required Duration duration,
VoidCallback? onEnd,
})
AnimatedCrossFade
AnimatedCrossFade
用于两个组件切换,动效是渐现效果。同时若两个子组件的尺寸不同,可以使用 layoutBuilder
来平滑过渡尺寸的变化。两个子组件的动画曲线可以单独配置。最简单的应用就是更改两个要切换的子组件的显示,代码如下所示:
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,
)
AnimatedCrossFade
的构造方法如下,其中 layoutBuilder
默认的组件布局构建方法。
const AnimatedCrossFade({
Key? key,
required this.firstChild,
required this.secondChild,
this.firstCurve = Curves.linear,
this.secondCurve = Curves.linear,
this.sizeCurve = Curves.linear,
this.alignment = Alignment.topCenter,
required this.crossFadeState,
required this.duration,
this.reverseDuration,
this.layoutBuilder = defaultLayoutBuilder,
})
AnimatedDefaultTextStyle
AnimatedDefaultTextStyle
用于文字样式动画效果,如果想自己控制字体变化过程(比如停留在中中间状态),可以使用DefaultTextStyleTransition 来完成。下面的动图是官网的效果,利用字体过渡的动画可以做品牌文字类的动画,可以加深用户的印象。
AnimatedDefaultTextStyle
的构造方法如下。
const AnimatedDefaultTextStyle({
Key? key,
required this.child,
required this.style,
this.textAlign,
this.softWrap = true,
this.overflow = TextOverflow.clip,
this.maxLines,
this.textWidthBasis = TextWidthBasis.parent,
this.textHeightBehavior,
Curve curve = Curves.linear,
required Duration duration,
VoidCallback? onEnd,
})
AnimatedList
const AnimatedList({
Key? key,
required this.itemBuilder,
this.initialItemCount = 0,
this.scrollDirection = Axis.vertical,
this.reverse = false,
this.controller,
this.primary,
this.physics,
this.shrinkWrap = false,
this.padding,
this.clipBehavior = Clip.hardEdge,
})
AnimatedModalBarrier
AnimatedModelBarrier
是 ModalBarrier
的替换,可以挡住它下层的组件,使得这些组件无法与用户交互,并且在组件上加一层颜色动画过渡遮罩。AnimatedModelBarrier
的构造方法如下。其中 dismissible
参数如果为 true
,则点击遮罩时会退出当前页面返回到上一页。
const AnimatedModalBarrier({
Key? key,
required Animation<Color?> color,
bool dismissible,
String? semanticsLabel,
bool? barrierSemanticsDismissible
})
可以使用AnimatedModalBarrier
做自定义弹层,当要弹出弹层时,使用 AnimatedModalBarrier
遮挡底层,然后再在它上层叠加新的组件就可以实现弹层的效果。下面是我们实现的一个示例,点击按钮后弹出一个遮罩层,然后遮罩上加了一个文字层。
AnimatedOpacity
AnimatedPhysicalModel
控制组件的阴影、颜色、边框圆弧等物理模型,但组件自身的形状不发生改变。比如下图是官方给了一个更改阴影的例子,虽然组件自己没有变,但是因为阴影的变化,感觉却像是推开了一道缝隙一样,也挺有趣的。
AnimatedPhysicalModel
的构造方法如下,其中颜色和阴影颜色是通过两个布尔值 animateColor
和 animateShadowColor
决定是否要通过动画显示的。
const AnimatedPhysicalModel({
Key? key,
required Widget child,
required BoxShape shape,
Clip clipBehavior,
BorderRadius borderRadius,
required double elevation,
required Color color,
bool animateColor,
required Color shadowColor,
bool animateShadowColor,
Curve curve = Curves.linear,
required Duration duration,
VoidCallback? onEnd
})
下面是一段示例代码,通过更改elevation
属性实现Z 轴阴影的变化,同时做了颜色的过渡动画效果:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AnimatedPhysicalModel 动画'),
),
body: Center(
child: AnimatedPhysicalModel(
child: Container(
width: 300,
height: 300,
),
duration: Duration(seconds: 1),
color: _elevation == 0.0 ? Colors.blue : Colors.green,
animateColor: true,
animateShadowColor: true,
elevation: _elevation,
shape: BoxShape.circle,
shadowColor: Colors.blue[900]!,
curve: Curves.easeInOutCubic,
),
),
floatingActionButton: FloatingActionButton(
child: Text(
'Play',
style: TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
),
onPressed: () {
setState(() {
_elevation = _elevation == 0 ? 10.0 : 0.0;
});
},
),
);
}
AnimatedSize
子组件的尺寸变化动画组件,通过尺寸的改变可以做放大缩小的效果,下面是官方的一个示例,点击组件的时候更改组件的尺寸,感觉是缩放一样。
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => _updateSize(),
child: Container(
color: Colors.amberAccent,
child: AnimatedSize(
curve: Curves.easeIn,
duration: const Duration(seconds: 1),
child: FlutterLogo(size: _size),
),
),
);
}
总结
本篇列举了 Flutter 隐式动画的12个基础组件,普通的动画效果依赖这些组件基本就能搞定了。而如果需要转换类的动画效果需要使用 Transition
来支持,下篇岛上码农为你整理一下 Transition
类的动画组件。源码可以到这里下载:动画组件演示示例源码。
号外
转载自:https://juejin.cn/post/7026341666072035359