在 Flutter 中,有多种方式为 Widget
添加动画。动画可以通过内置的动画控件、动画库、以及自定义动画来实现。下面我们将探讨 Flutter 中几种常用的动画方式,包括隐式动画、显式动画以及动画控制器的使用。
1. 隐式动画(Implicit Animations)
Flutter 提供了许多隐式动画类,它们可以在属性发生变化时自动进行动画过渡,而不需要显式地定义动画控制器。常用的隐式动画包括 AnimatedContainer
、AnimatedOpacity
、AnimatedPositioned
等。
示例:AnimatedContainer
import 'package:flutter/material.dart';
class ImplicitAnimationExample extends StatefulWidget {
@override
_ImplicitAnimationExampleState createState() => _ImplicitAnimationExampleState();
}
class _ImplicitAnimationExampleState extends State<ImplicitAnimationExample> {
bool _isExpanded = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Implicit Animation")),
body: Center(
child: AnimatedContainer(
width: _isExpanded ? 200.0 : 100.0,
height: _isExpanded ? 200.0 : 100.0,
color: _isExpanded ? Colors.blue : Colors.red,
duration: Duration(seconds: 1),
curve: Curves.easeInOut,
child: InkWell(
onTap: () {
setState(() {
_isExpanded = !_isExpanded;
});
},
child: Center(
child: Text(
"Tap Me!",
style: TextStyle(color: Colors.white),
),
),
),
),
),
);
}
}
void main() => runApp(MaterialApp(home: ImplicitAnimationExample()));
-
AnimatedContainer
:当width
、height
或color
发生变化时,它将自动进行平滑过渡动画。 -
duration
:定义动画时长。 -
curve
:定义动画的速率曲线(比如线性、缓入缓出等)。
2. 显式动画(Explicit Animations)
显式动画比隐式动画更灵活,但需要手动管理动画控制器。常见的显式动画类包括 AnimationController
、Tween
和 AnimatedBuilder
。
示例:AnimationController
+ Tween
import 'package:flutter/material.dart';
class ExplicitAnimationExample extends StatefulWidget {
@override
_ExplicitAnimationExampleState createState() => _ExplicitAnimationExampleState();
}
class _ExplicitAnimationExampleState extends State<ExplicitAnimationExample> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
@override
void initState() {
super.initState();
// 创建 AnimationController 并设置动画时长
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
// 使用 Tween 来定义动画范围
_animation = Tween<double>(begin: 100.0, end: 200.0).animate(_controller)
..addListener(() {
setState(() {}); // 监听动画并更新 UI
});
// 开始动画
_controller.forward();
}
@override
void dispose() {
// 销毁控制器以避免内存泄漏
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Explicit Animation")),
body: Center(
child: Container(
width: _animation.value,
height: _animation.value,
color: Colors.blue,
child: Center(child: Text("Animating", style: TextStyle(color: Colors.white))),
),
),
);
}
}
void main() => runApp(MaterialApp(home: ExplicitAnimationExample()));
-
AnimationController
:负责控制动画的生命周期(开始、停止等)。 -
Tween
:定义动画的起点和终点。 -
animate
:将Tween
与控制器绑定,从而生成一个可以被监听的Animation
对象。
3. AnimatedBuilder
与 CustomPainter
AnimatedBuilder
提供了一种更优化的方式来构建动画,它会只重新绘制动画相关的部分,而不是整个 widget 树。
示例:AnimatedBuilder
import 'package:flutter/material.dart';
class AnimatedBuilderExample extends StatefulWidget {
@override
_AnimatedBuilderExampleState createState() => _AnimatedBuilderExampleState();
}
class _AnimatedBuilderExampleState extends State<AnimatedBuilderExample> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_animation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
_controller.repeat(reverse: true); // 动画来回循环
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("AnimatedBuilder Example")),
body: Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.scale(
scale: _animation.value * 2, // 动画控制缩放
child: child,
);
},
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green,
child: Center(
child: Text("Scaling", style: TextStyle(color: Colors.white)),
),
),
),
),
);
}
}
void main() => runApp(MaterialApp(home: AnimatedBuilderExample()));
-
AnimatedBuilder
:用于监听动画并在每一帧更新时调用builder
,使动画更加高效。 -
Transform.scale
:使用动画值来缩放child
。
4. 其他动画组件
-
Hero
动画:在两个页面间进行共享元素动画时使用。 -
FadeTransition
、ScaleTransition
、RotationTransition
:这些是 Flutter 提供的显式动画小部件,方便实现简单的动画效果。