CurvedAnimation
也是Animation
的实现,只不过它可以根据Curve
曲线来生成非线性的区间值。CurvedAnimation
并不能驱动动画,它只是一个数值的转换器。我们可以通过CurvedAnimation来指定动画的曲线。
CurvedAnimation
类接受三个参数:
- parent:参数传入一个Animation对象,比如AnimationController
- curve:控制动画变化的速率
- reverse:反转曲线的方向
CurvedAnimation({
required this.parent,
required this.curve,
this.reverseCurve,
})
用法:
//通过CurvedAnimation来指定动画的曲线
final _curvedAnimation = CurvedAnimation(
parent: _controller,
curve: Curves.bounceOut
);
- 例子1:
结合上一章Animation
里的例子中并没有指定Curve
,所以放大的过程是线性的(匀速),下面我们指定一个Curve
,来实现一个类似于弹簧效果的动画过程。我们只需要将initState
中的代码改为下面这样即可:
void initState() {
// TODO: implement initState
super.initState();
//创建动画控制器
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this
);
//指定一个Curve
_animation = CurvedAnimation(parent: _controller, curve: Curves.bounceInOut);
//使用Tween图片宽高从0变到300
//_animation = Tween(begin: 0.0,end: 300.0).animate(_controller);
_animation = Tween(begin: 0.0,end: 300.0).animate(_animation);
//监听动画,并且更新ui
_controller.addListener(() {
setState(() {
//监听插值变化
print(_animation.value);
});
});
_controller.addStatusListener((status) {
print(status);
//AnimationStatus.forward(动画正在正向执行)
//AnimationStatus.completed( 动画在终点停止)
//AnimationStatus.dismissed(动画在起始点停止)
//AnimationStatus.reverse(动画正在反向执行)
});
//启动动画正向执行
_controller.forward();
}
- 例子2:
结合上章AnimationController
的篮球弹跳例子,我们给弹跳动画加上curve
。那么球弹跳的动作就比较流畅
import 'package:flutter/material.dart';
class CurvedAnimationPage extends StatefulWidget {
const CurvedAnimationPage({Key? key}) : super(key: key);
@override
State<CurvedAnimationPage> createState() => _CurvedAnimationPageState();
}
class _CurvedAnimationPageState extends State<CurvedAnimationPage> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
// TODO: implement initState
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this
);
final curvedAnimation = CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn
);
//通过Tween来生成不同的区间范围值,Tween不保存任何状态,它只是起始值的变换函数。
_animation = Tween<double>(begin:600 ,end: 400).animate(curvedAnimation);
_controller.addListener(() {
//监听插值变化
setState(() {
//print(_animation.value);
});
});
_controller.repeat(reverse: true);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('CurvedAnimation'),),
body: Stack(
children: [
Image.asset(
'images/qiuc.jpeg',
fit: BoxFit.cover,
height: double.infinity,
width: double.infinity,
),
Transform.translate(
offset: Offset(250,_animation.value),//改变y的偏移量
child: Image.asset(
'images/qiu.png',
fit: BoxFit.contain,
height: 70,
width: 70,
),
)
],
),
);
}
}
效果: