AnimatedContainer
(隐式动画)
AnimatedContainer
可以说是带动画的容器,使用AnimatedContainer
可以很方便的实现Widget
的动画效果。
因为 AnimatedContainer
是隐式动画,所以不需要控制器来控制动画。
AnimatedContainer
只需要提供动画开始值和结束值,它就会动起来并不需要我们主动调用setState
方法。
- 构造函数
AnimatedContainer({
super.key,
this.alignment,
this.padding,
Color? color,
Decoration? decoration,
this.foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
this.margin,
this.transform,
this.transformAlignment,
this.child,
this.clipBehavior = Clip.none,
super.curve,
required super.duration,//必须
super.onEnd,//结束动画
})
例子: 隐式动画不需要创建动画控制器,例子的控制器是球弹跳动画的。
import 'package:flutter/material.dart';
class AnimatedContainerPage extends StatefulWidget {
const AnimatedContainerPage({Key? key}) : super(key: key);
@override
State<AnimatedContainerPage> createState() => _AnimatedContainerPageState();
}
class _AnimatedContainerPageState extends State<AnimatedContainerPage> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
//用户点击时启动动画
bool isAnimating = false;
@override
void initState() {
// TODO: implement initState
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this
)..repeat(reverse: true);
final curvedAnimation = CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn
);
//通过Tween来生成不同的区间范围值,Tween不保存任何状态,它只是起始值的变换函数。
_animation = Tween<double>(begin:0 ,end: -300).animate(curvedAnimation);
_controller.addListener(() {
//监听插值变化
setState(() {
// print(_animation.value);
});
});
}
@override
void dispose() {
// TODO: implement dispose
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('AnimatedContainer'),),
body: SafeArea(
child: Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Column(
children: [
Transform.translate(
offset: Offset(0,_animation.value),
child: Image.asset(
'images/qiu.png',
fit: BoxFit.contain,
height: 70,
width: 70,
),
),
GestureDetector(
//当用户在容器内部点击时,isAnimating变量的值将会改变
onTap: (){
setState(() {
isAnimating = !isAnimating;
});
},
child: AnimatedContainer(
duration: const Duration(seconds: 5),
height: isAnimating ? 200: 20,
width: isAnimating ? MediaQuery.of(context).size.width*0.8 :60,
curve: isAnimating ? Curves.bounceIn : Curves.bounceOut,
decoration: BoxDecoration(
color: isAnimating ? Colors.green: Colors.blue,
borderRadius: isAnimating ? const BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30)
) :const BorderRadius.all(Radius.circular(0)),
border: Border.all(
color: isAnimating ? Colors.orange :Colors.red,
width: isAnimating? 8 :2
),
),
),
)
],
)
)
],
),
)
);
}
}
效果: