简单动画
学习在 Flutter 中实现动画的最简单方式。
Flutter 提供丰富的动画 API,开始使用它们的最简单方式是 隐式动画 (implicit animations)。「隐式动画」指一类 widget,它们会自动为属性变化添加动画,而你无需管理任何中间行为。
你将完成的内容
在本课中,你将了解最常见、最灵活的隐式动画 widget 之一:AnimatedContainer。只需额外两行代码,每个 Tile 的背景色会在大约半秒内动画过渡到新颜色。
步骤
1
将 Container 转换为 AnimatedContainer
将 Container 转换为 AnimatedContainer
目前,Tile.build 方法返回 Container 来显示字母。当 hitType 变化时,例如从 HitType.none 变为 HitType.hit,方块背景色会瞬间改变。例如,在 HitType.none 到 HitType.hit 的情况下从白色变为绿色。
作为参考,这是 Tile widget 的当前实现:
class Tile extends StatelessWidget {
const Tile(this.letter, this.hitType, {super.key});
final String letter;
final HitType hitType;
@override
Widget build(BuildContext context) {
return Container(
height: 60,
width: 60,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
color: switch (type) {
HitType.hit => Colors.green,
HitType.partial => Colors.yellow,
HitType.miss => Colors.grey,
_ => Colors.white,
},
),
child: Center(
child: Text(
letter.toUpperCase(),
style: Theme.of(context).textTheme.titleLarge,
),
),
);
}
}
要使颜色变化平滑动画,将 Container widget 替换为 AnimatedContainer。
AnimatedContainer 类似 Container,但会在指定的 duration 内自动为属性变化添加动画。当 color、height、width、decoration
或 alignment 等属性变化时,
AnimatedContainer 会在旧值和新值之间插值,产生平滑过渡。
按如下方式修改 Tile widget:
class Tile extends StatelessWidget {
const Tile(this.letter, this.hitType, {super.key});
final String letter;
final HitType hitType;
@override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: Duration(milliseconds: 500),
height: 60,
width: 60,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
color: switch (hitType) {
HitType.hit => Colors.green,
HitType.partial => Colors.yellow,
HitType.miss => Colors.grey,
_ => Colors.white,
},
),
child: Center(
child: Text(
letter.toUpperCase(),
style: Theme.of(context).textTheme.titleLarge,
),
),
);
}
}
duration 是必填属性,用于指定动画应持续多久。在本例中,传入 Duration(milliseconds: 500) 表示颜色过渡将耗时半秒。你也可以指定秒、分钟以及许多其他时间单位。
现在,当 hitType 变化且 Tile widget 重建时(因为在 GamePage 中调用了 setState),方块颜色会在指定的 duration 内从其旧颜色平滑动画过渡到新颜色。
2
调整动画曲线
调整动画曲线
要为隐式动画增加一点自定义,可以传入不同的 Curve。不同曲线会在动画过程中的不同点改变动画速度。
例如,Flutter 动画的默认曲线是 Curves.linear。此 gif 展示该动画曲线的表现:
与之对比,Curve.bounceIn 是另一种常见曲线:
要更改此动画的 Curve,将代码更新为以下内容:
class Tile extends StatelessWidget {
const Tile(this.letter, this.hitType, {super.key});
final String letter;
final HitType hitType;
@override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: Duration(milliseconds: 500),
curve: Curves.bounceIn, // NEW
height: 60,
width: 60,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
color: switch (hitType) {
HitType.hit => Colors.green,
HitType.partial => Colors.yellow,
HitType.miss => Colors.grey,
_ => Colors.white,
},
),
child: Center(
child: Text(
letter.toUpperCase(),
style: Theme.of(context).textTheme.titleLarge,
),
),
);
}
}
Flutter SDK 提供了许多不同曲线,因此欢迎通过向 curve 参数传入不同类型来尝试。
像 AnimatedContainer 这样的隐式动画很强大,因为你只需告诉 widget 新状态应该是什么,它会处理动画的「如何」实现。
对于复杂的自定义动画,你可以编写自己的动画 widget。如果你感兴趣,可在 动画教程中尝试。
3
回顾
回顾
你已完成的内容
以下是你本课构建与学习内容的摘要。了解了隐式动画
隐式动画是会自动为属性变化添加动画的 widget。你指定新状态,widget 会为你处理动画,无需手动管理动画。
使用 AnimatedContainer 为方块添加动画
通过将 Container 替换为 AnimatedContainer 并添加 duration,你的方块现在会在颜色之间平滑过渡。仅用两行代码,就为应用增添了专业质感!
用 duration 和 curve 自定义时序
duration 属性控制动画持续多久,而 curve 改变动画的感觉。你尝试了 Curves.decelerate,也可以尝试其他值,例如
Curves.easeIn、Curves.bounceOut 或 Curves.elasticIn。
完成了 Birdle 游戏
你已构建完整的 Wordle 风格游戏,包含自定义 widget、动态布局、用户输入、状态管理和流畅动画。你现在具备构建自己的 Flutter 应用的基础技能!
4
自测
自测
隐式动画测验
1 / 2-
Container
不正确。
Container 不会添加动画;属性变化会瞬间发生。
-
AnimatedContainer
正确!
AnimatedContainer 会在指定的 duration 内自动为其属性变化添加动画。
-
AnimationController
不正确。
AnimationController 用于显式动画;AnimatedContainer 更适合基础动画且更简单。
-
TransitionContainer
不正确。
没有 TransitionContainer widget;隐式动画请使用 AnimatedContainer。
duration 属性控制什么?
-
widget 在消失前停留在屏幕上的时长。
不正确。
duration 控制动画时长,而非 widget 可见性。
-
动画从旧值过渡到新值所需的时间。
正确!
duration 指定属性变化被动画化的时间长度。
-
动画开始前的延迟。
不正确。
duration 关乎动画长度;延迟需要单独配置。
-
动画重复的次数。
不正确。
隐式动画在每次状态变化时运行一次;重复需要显式动画控制器。
除非另有说明,本文档之所提及适用于 Flutter 3.44.0 版本。本页面最后更新时间:2026-06-18。查看文档源码 或者 为本页面内容提出建议。