呼,这段时间工作有点忙碌起来了,所以都是挤出时间来学习,所以有不对的地方希望各位大佬多多指点
Animation 是动画的核心类,但是他与UI的渲染是没有关系的!!!!没关系的!!他们俩是清白的!!(所以下面就会说到第一种方法为什么一定要用到setState来进行渲染ui)
Animation是一个抽象类,Animation对象的数值和动画状态都是通过他获取的!
而AnimationController是管理Animation的控制器,他管理着Animation对象的资源(回收工作也是他控制的),而资源是怎么管理的呢?通过这个参数vsync:
截屏2021-03-23 下午4.16.51.png
Tween
默认情况下,AnimationController对象的范围从0.0到1.0。如果您需要不同的范围或不同的数据类型,则可以使用Tween来配置动画以生成不同的范围或数据类型的值。
Tween是一个无状态(stateless)对象,需要begin和end值。Tween的唯一职责就是定义从输入范围到输出范围的映射。输入范围通常为0.0到1.0,但这不是必须的。
理解了这几个重要类,那么开始撸代码了
方法一:利用setState组合实现动画效果
class LogoApp extends StatefulWidget {
@override
_LogoAppState createState() => _LogoAppState();
}
class _LogoAppState extends State<LogoApp> with SingleTickerProviderStateMixin {
Animation<double> animation;
AnimationController controller;
//动画的状态
AnimationStatus animationStatus;
double animationValue;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 2));
animation = Tween<double>(begin: 0, end: 300).animate(controller)
//动画变化效果必须有setState
..addListener(() {
//监听动画变化的值,例如:0到300
setState(() {
animationValue = animation.value;
});
})
..addStatusListener((status) {
setState(() {
animationStatus = status;
});
});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 50),
child: Column(
children: [
GestureDetector(
onTap: () {
//恢复原本状态
controller.reset();
//继续播放
controller.forward();
},
//textDirection设定文本显示的方式,TextDirection.ltr设定为从左往右
child: Text(
"start",
textDirection: TextDirection.ltr,
),
),
Text(
'State:${animationStatus.toString()}',
textDirection: TextDirection.ltr,
),
Text(
'State:${animationValue.toString()}',
textDirection: TextDirection.ltr,
),
Container(
height: animation.value,
width: animation.value,
child: FlutterLogo(),
)
],
),
);
}
}
方法二:通过AnimatedWidget是实现动画
class AnimatedLoge extends AnimatedWidget {
AnimatedLoge({Key key, Animation<double> animation})
: super(key: key, listenable: animation);
@override
Widget build(BuildContext context) {
final Animation<double> animation=listenable;
return Center(
child: Container(
margin: EdgeInsets.symmetric(vertical: 10),
width: animation.value,
height: animation.value,
child: FlutterLogo(),
),
);
}
}
class AnimationWidget extends StatefulWidget {
@override
_AnimationWidgetState createState() => _AnimationWidgetState();
}
class _AnimationWidgetState extends State<AnimationWidget> with SingleTickerProviderStateMixin{
Animation<double> animation;
AnimationController controller;
@override
void initState() {
super.initState();
controller=AnimationController(duration: Duration(seconds: 2),vsync: this);
animation=Tween<double>(begin: 0,end: 300).animate(controller);
controller.forward();
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
// return AnimatedLoge(animation: animation);
}
}
方法三:
而这个方法会更加灵活的创建你所希望的动画效果,因为他把职责分为了三部分
1、显示logo(LogWidget例子中在这个类实现)
2、定义Animation对象(_AnimationWidgetState例子中在这个类实现)
3、渲染过渡效果(GrowTransition例子中在这个类实现)
class AnimationWidget extends StatefulWidget {
@override
_AnimationWidgetState createState() => _AnimationWidgetState();
}
class _AnimationWidgetState extends State<AnimationWidget> with SingleTickerProviderStateMixin{
Animation<double> animation;
AnimationController controller;
@override
void initState() {
super.initState();
controller=AnimationController(duration: Duration(seconds: 2),vsync: this);
animation=Tween<double>(begin: 0,end: 300).animate(controller);
controller.forward();
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return GrowTransition(child: LogWidget(),animation: animation,);
}
}
class LogWidget extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: FlutterLogo(),
);
}
}
class GrowTransition extends StatelessWidget{
GrowTransition({this.child, this.animation});
final Widget child;
final Animation<double> animation;
@override
Widget build(BuildContext context) {
return AnimatedBuilder(animation: animation, builder: (context,child)=>Container(
height: animation.value,
width: animation.value,
child: child,
),child:child,);
}
}
好啦!我要继续去学习下一步,Hero动画
网友评论