AnimationStatus.dismissed(动画初始状态)
AnimationStatus.completed(动画结束状态)
AnimationStatus.forward(动画处在从开始到结束的运行状态)
AnimationStatus.reverse(动画处在从结束到开始的运行状态)
在指定时间内,将组织属性值由初始值演变到终止值。从而形成动画效果
参数
duration(动画的执行时间)
reverseDuration(动画反向执行时间)
lowerBound=0.0(动画最小值)
upperBound=1.0(动画最大值)
value(动画初始值,默认是lowerBound)
vsync(TickerProvider类型的对象,用来创建Ticker对象)
当创建一个AnimationController时,需要传递一个vsync参数
AnimationController具有控制动画的方法
.forward()-可以正向执行动画
.reverse()-可以反向执行动画
.dispose()-用来释放动画资源(在不使用时需要调用该方法,否则会造成资源泄露)
.stop()-用来停止动画执行
AnimationController动画生产值的默认区间是0.0到0.1,如果希望使用不同的区间,或不同的数据类型,需要使用Tween
Tween的唯一职责就是定义从输入范围到输出范围的映射
Tween(begin,end)
ColorTween(begin:Colors.颜色,end:Colors.颜色)
parent(动画控制器对象)
curve(正向执行的动画曲线)
reverseCurve(反向执行的动画曲线)
class AnimationDemo extends StatefulWidget {
const AnimationDemo({Key? key}) : super(key: key);
@override
State<AnimationDemo> createState() => _AnimationDemoState();
}
class _AnimationDemoState extends State<AnimationDemo>
with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation animation;
@override
void initState() {
// TODO: implement initState
super.initState();
//1.创建 AnimationController
controller =
AnimationController(duration: Duration(milliseconds: 400), vsync: this);
//2.声明动画曲线
animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn);
//3.设置动画值的范围
animation = Tween(begin: 50.0, end: 300.0).animate(controller);
//4.监听动画
animation.addListener(() {
print(animation.value);
setState(() {});
});
//5.执行动画
//controller.forward();
}
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
controller.forward();
},
child: Text('放大')),
ElevatedButton(
onPressed: () {
controller.reverse();
},
child: Text('缩小')),
ElevatedButton(
onPressed: () {
animation.addStatusListener((status) {
if (status == AnimationStatus.completed) {
//反向执行动画
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
//正向
controller.forward();
}
});
controller.forward();
},
child: Text('重复')),
ElevatedButton(
onPressed: () {
controller.stop();
},
child: Text('停止')),
Icon(
Icons.accessible_forward_outlined,
color: Colors.blue,
size: animation.value,
),
Opacity(
opacity: controller.value,
child: Text('hello world'),
)
],
),
);
}
//切换至后台的时候会调用来释放资源
@override
void dispose() {
// TODO: implement dispose
super.dispose();
controller.dispose();
}
}
class StaggerAnimationDemo extends StatefulWidget {
const StaggerAnimationDemo({Key? key}) : super(key: key);
@override
State<StaggerAnimationDemo> createState() => _StaggerAnimationDemoState();
}
class _StaggerAnimationDemoState extends State<StaggerAnimationDemo>
with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation<double> animation;
late Animation sizeAnimation;
late Animation colorAnimation;
late Animation rotationAnimation;
@override
void initState() {
// TODO: implement initState
super.initState();
//1.创建 AnimationController
controller =
AnimationController(duration: Duration(seconds: 3), vsync: this);
//2.创建动画
animation = CurvedAnimation(parent: controller, curve: Interval(0.0, 0.5))
..addListener(() {});
//3.让动画反复运行
animation.addStatusListener((status) {
if (status == AnimationStatus.completed) {
//反向执行动画
controller.reverse();
} else if (status == AnimationStatus.dismissed) {
//正向
controller.forward();
}
});
//4.设置其他动画
sizeAnimation = Tween(begin: 0.0, end: 200.0).animate(animation); //需要将animation设为
colorAnimation = ColorTween(begin: Colors.yellow, end: Colors.red).animate(
CurvedAnimation(
parent: controller,
curve: Interval(0.5, 0.8, curve: Curves.bounceIn)))
..addListener(() {
setState(() {});
});
rotationAnimation = Tween(begin: 0.0, end: 2 * pi).animate(CurvedAnimation(
parent: controller,
curve: Interval(0.8, 1.0, curve: Curves.easeIn),
));
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
controller.forward();
},
child: Text('重复')),
ElevatedButton(
onPressed: () {
controller.stop();
},
child: Text('停止')),
Icon(
Icons.accessible_forward_outlined,
color: Colors.blue,
size: animation.value,
),
Opacity(
opacity: controller.value,
child: Transform.rotate(
angle: rotationAnimation.value,
child: Container(
width: sizeAnimation.value,
color: colorAnimation.value,
height: sizeAnimation.value,
),
))
],
),
);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
controller.dispose();
}
}
class HeroAnimationDemo extends StatelessWidget {
const HeroAnimationDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 50),
child: GridView.extent(
maxCrossAxisExtent: 300.0,
mainAxisSpacing: 20,
children: List.generate(20, (index){
String imageURL='https://picsum.photos/id/$index/300/400';
return GestureDetector(
onTap:(){
Navigator.push(context, MaterialPageRoute(builder: (BuildContext ctx){
return ImageDetail(imageURL);
}));
},
child: Hero(
tag: imageURL,
child: Image.network(imageURL),
),
);
}),
),
);
}
}
class ImageDetail extends StatelessWidget {
final String imageURl;
ImageDetail(this.imageURl);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: GestureDetector(
onTap: (){
//调回去
Navigator.pop(context);
},
child: Hero(
tag: imageURl,
child: Image.network(
imageURl,
width: double.infinity,
fit: BoxFit.cover,
),
),
),
),
);
}
}