
到目前为止,你已经掌握了:
但是,一个静态页面的 App 很无趣。 Flutter 提供了丰富的动画组件,让 UI 更加生动。
类型 | 组件 | 说明 |
|---|---|---|
隐式动画 | AnimatedContainer, AnimatedOpacity, AnimatedPadding, AnimatedAlign | 属性变化自动过渡动画,无需 AnimationController |
显式动画 | AnimationController + Tween + AnimatedBuilder | 完全可控动画,适合复杂效果 |
页面过渡 | PageRouteBuilder, Hero | 页面切换动画,元素过渡动画 |
本篇先从 隐式动画 入门。
class AnimatedContainerDemo extends StatefulWidget{
@override
_AnimatedContainerDemoState createState() => _AnimatedContainerDemoState();
}
class _AnimatedContainerDemoState extends State<AnimatedContainerDemo> {
double _width = 100;
double _height = 100;
Color _color = Colors.blue;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('AnimatedContainer 示例')),
body: Center(
child: AnimatedContainer(
width: _width,
height: _height,
color: _color,
duration: Duration(seconds: 1),
curve: Curves.easeInOut,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_width = _width == 100 ? 200 : 100;
_height = _height == 100 ? 200 : 100;
_color = _color == Colors.blue ? Colors.orange : Colors.blue;
});
},
child: Icon(Icons.play_arrow),
),
);
}
}
📌 功能解析:
实现淡入淡出效果:
AnimatedOpacity(
opacity: _visible ? 1.0 : 0.0,
duration: Duration(seconds: 1),
child: Container(
width: 100,
height: 100,
color: Colors.green,
),
)
📌 配合 setState 切换 _visible,即可实现淡入淡出动画
实现位置平滑移动:
AnimatedAlign(
alignment: _align,
duration: Duration(seconds: 1),
child: FlutterLogo(size: 80),
)
onPressed: () {
setState(() {
_align = _align == Alignment.topLeft ? Alignment.bottomRight : Alignment.topLeft;
});
}
📌 平滑移动元素到不同位置
class ScaleAnimationDemo extends StatefulWidget {
@override
_ScaleAnimationDemoState createState() => _ScaleAnimationDemoState();
}
class _ScaleAnimationDemoState extends State<ScaleAnimationDemo> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
_animation = Tween<double>(begin: 0, end: 1).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('显式动画示例')),
body: Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.scale(
scale: _animation.value,
child: FlutterLogo(size: 100),
);
},
),
),
);
}
}
📌 功能解析:
Hero(
tag: 'logo',
child: FlutterLogo(size: 80),
)
在跳转页面也使用相同 tag,即可实现元素平滑过渡
Navigator.push(context, PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => DetailPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(opacity: animation, child: child);
},
));
📌 页面切换时淡入淡出效果
❌ 忘记 dispose AnimationController → 内存泄漏 ❌ duration 设置为 0 → 动画无效 ❌ AnimatedBuilder 未传 animation → 不会刷新 ❌ Hero tag 冲突 → 页面过渡异常
📌 建议:
你已经学会:
📌 到这里为止:
你的 App 已经具备基本动画交互能力 ✅
隐式动画快速简单 显式动画精确可控 Hero / PageRouteBuilder 页面过渡动画 App 更生动、更有交互感
《Flutter 零基础入门(四十四):Flutter 图标与图片资源管理 —— 视觉元素实战》
下一篇我们将学习:
🚀 让你的 App 更加美观生动