RotationTransition 继承于AnimatedWidget,是一个提供旋转功能的Widget,需要传入参数 Animation
设
Animation
中的值为 v,则旋转的弧度是 v * 2 * π
/// 会重复播放的控制器
late final AnimationController _repeatController;
/// 线性动画
late final Animation<double> _animation;
@override
void initState() {
super.initState();
/// 动画持续时间是 3秒,此处的this指 TickerProviderStateMixin
_repeatController = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
)
..repeat(); // 设置动画重复播放
// 创建一个从0到360弧度的补间动画 v * 2 * π
_animation = Tween<double>(begin: 0, end: 1).animate(_repeatController);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RotationTransition(
turns: _animation,
child: const Icon(Icons.arrow_drop_up, size: 180),
),
),
);
}
实现方式与线性变化的旋转动画类似,只是需要将 Tween
更改为 CurvedAnimation
class _RotationTransitionPageState extends State<RotationTransitionPage>
with TickerProviderStateMixin {
/// 会重复播放的控制器
late final AnimationController _repeatController;
/// 非线性动画
late final Animation<double> _curveAnimation;
@override
void initState() {
super.initState();
_repeatController = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
)..repeat();
/// Curves 存在多种模式,具体的效果查看Curves源码,有链接展示动画效果
_curveAnimation = CurvedAnimation(
parent: _repeatController,
curve: Curves.easeInCirc,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RotationTransition(
turns: _curveAnimation,
child: const Icon(Icons.arrow_drop_up, size: 180),
),
),
);
}
}
实现思路:监听动画的状态,每当动画播放完成时延时一段时间,然后启动动画开始播放。
class _RotationTransitionPageState extends State<RotationTransitionPage>
with TickerProviderStateMixin {
/// 重复播放前需要停顿一下的控制器
late final AnimationController _delayRepeatController;
/// 延时重复播放动画
late final Animation<double> _delayAnimation;
@override
void initState() {
super.initState();
_delayRepeatController = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
)
// 添加动画监听
..addListener(() {
// 获取动画当前的状态
var status = _delayRepeatController.status;
if (status == AnimationStatus.completed) {
// 延时1秒
Future.delayed(const Duration(seconds: 1), () {
//从0开始向前播放
_delayRepeatController.forward(from: 0.0);
});
}
})
..forward();
_delayAnimation =
Tween<double>(begin: 0, end: 1).animate(_delayRepeatController);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RotationTransition(
turns: _delayAnimation,
child: const Icon(Icons.arrow_drop_up, size: 180),
),
),
);
}
}
实现方式:使用 AnimationController 的
animateTo
函数。
class _RotationTransitionPageState extends State<RotationTransitionPage>
with TickerProviderStateMixin {
/// 手动控制动画的控制器
late final AnimationController _manualController;
/// 手动控制
late final Animation<double> _manualAnimation;
@override
void initState() {
super.initState();
/// 不设置重复,使用代码控制进度,动画时间1秒
_manualController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_manualAnimation =
Tween<double>(begin: 0, end: 1).animate(_manualController);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RotationTransition(
turns: _manualAnimation,
child: CupertinoButton(
onPressed: () {
/// 获取动画当前的值
var value = _manualController.value;
/// 0.5代表 180弧度
if (value == 0.5) {
_manualController.animateTo(0);
} else {
_manualController.animateTo(0.5);
}
},
child: const Icon(Icons.arrow_drop_up, size: 180),
),
),
),
);
}
}
别忘了释放AnimationController 资源。
@override
void dispose() {
_controller.dispose();
super.dispose();
}