实现 Flutter 动画的方法有很多,Flutter 提供了强大的动画框架,以下是常见的几种实现方法:
1. 基于 Tween 和 AnimationController
这种方法最常用,适合需要自定义动画的场景。
步骤:
- 创建一个
AnimationController。 - 创建一个
Tween,并将其与AnimationController绑定。 - 在
AnimationController的addListener方法中调用setState以重绘 Widget。
示例代码:
class MyAnimationWidget extends StatefulWidget {
@override
_MyAnimationWidgetState createState() => _MyAnimationWidgetState();
}
class _MyAnimationWidgetState extends State<MyAnimationWidget> 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, end: 300).animate(_controller)
..addListener(() {
setState(() {});
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
width: _animation.value,
height: _animation.value,
color: Colors.blue,
);
}
}
2. 使用 AnimatedWidget
AnimatedWidget 封装了 addListener 和 setState,使得代码更简洁。
示例代码:
class MyAnimatedWidget extends AnimatedWidget {
MyAnimatedWidget({Key key, Animation<double> animation})
: super(key: key, listenable: animation);
@override
Widget build(BuildContext context) {
final Animation<double> animation = listenable;
return Container(
width: animation.value,
height: animation.value,
color: Colors.blue,
);
}
}
class MyAnimationWidget extends StatefulWidget {
@override
_MyAnimationWidgetState createState() => _MyAnimationWidgetState();
}
class _MyAnimationWidgetState extends State<MyAnimationWidget> 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, end: 300).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MyAnimatedWidget(animation: _animation);
}
}
3. 使用 AnimatedBuilder
AnimatedBuilder 进一步简化了动画的实现,它将动画和 Widget 的构建逻辑分离。
示例代码:
class MyAnimationWidget extends StatefulWidget {
@override
_MyAnimationWidgetState createState() => _MyAnimationWidgetState();
}
class _MyAnimationWidgetState extends State<MyAnimationWidget> 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, end: 300).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Container(
width: _animation.value,
height: _animation.value,
color: Colors.blue,
);
},
);
}
}
4. 使用内置的 AnimatedContainer
AnimatedContainer 是一个方便的动画实现方法,适合简单的动画需求。
示例代码:
class MyAnimatedContainer extends StatefulWidget {
@override
_MyAnimatedContainerState createState() => _MyAnimatedContainerState();
}
class _MyAnimatedContainerState extends State<MyAnimatedContainer> {
double _width = 50;
double _height = 50;
void _animateContainer() {
setState(() {
_width = _width == 50 ? 200 : 50;
_height = _height == 50 ? 200 : 50;
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _animateContainer,
child: AnimatedContainer(
width: _width,
height: _height,
color: Colors.blue,
duration: Duration(seconds: 1),
curve: Curves.easeInOut,
),
);
}
}
5. 使用 Hero 动画
Hero 动画适用于页面跳转时的共享元素动画。
示例代码:
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
},
child: Hero(
tag: 'hero-tag',
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: Hero(
tag: 'hero-tag',
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
),
),
);
}
}
总结
上述方法涵盖了 Flutter 动画实现的主要方式,具体选择哪种方法取决于具体的需求和复杂度。希望这些示例能帮助你更好地理解和实现 Flutter 动画。