AnimationController
-
AnimationController是动画控制器,它可以使用Container创建简单的动画
-
在本案例中我们将创建一个从屏幕顶部开始沿对角线移动球。
IOS下运行程序
创建项目
-
在lib目录下创建一个shape_animation.dart文件。
-
我们首先在该文件下添加一个Ball无状态类,使用它创建一个圆形。
class Ball extends StatelessWidget {
const Ball({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 100,
decoration: const BoxDecoration(
color: Colors.orangeAccent,
shape: BoxShape.circle,
),
);
}
}
-
然后我们创建一个有状态的ShapeAnimation类。
-
在_ShapeAnimationState中声明一个动画控制器,Animation<double>用来插入动画的值,pos储存运动的值。
late AnimationController _controller;
late Animation<double> _animation;
double pos = 0;
-
使用dispose释放控制器
@override
void dispose() {
_controller.dispose();
super.dispose();
}
-
这里面我们在state类上添加SingleTickerProviderStateMixin表示只有一个AnimationController的情况,如果要使用多个AnimationController,可以使用TickerProviderStateMixin来代替。
class _ShapeAnimationState extends State<ShapeAnimation>
with SingleTickerProviderStateMixin
-
在initState方法中添加Duration对象,来指定控制器关联的动画的时常。
-
Tween可以理解为是开始和结束的长度(因为没有对边界约束,可以自行根据屏幕调整起始和结束位置,以防溢出画面)。
-
vaync属性是需要使用TickerProvider
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: 300).animate(_controller)
..addListener(() {
moveBall();
});
}
完整代码
-
main.dart
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const ShapeAnimation(),
);
}
}
-
shape_animation.dart
class ShapeAnimation extends StatefulWidget {
const ShapeAnimation({super.key});
@override
State<ShapeAnimation> createState() => _ShapeAnimationState();
}
class _ShapeAnimationState extends State<ShapeAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
double pos = 0;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: 300).animate(_controller)
..addListener(() {
moveBall();
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void moveBall() {
setState(() {
pos = _animation.value;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('动画控制器'),
actions: [
IconButton(
onPressed: () {
_controller.reset();
_controller.forward();
},
icon: const Icon(Icons.run_circle))
],
),
body: Stack(
children: [
Positioned(
left: pos,
top: pos,
child: const Ball(),
)
],
),
);
}
}
class Ball extends StatelessWidget {
const Ball({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 100,
decoration: const BoxDecoration(
color: Colors.orangeAccent,
shape: BoxShape.circle,
),
);
}
}