Flutter(十五)——动画的封装与简化

举报
择城终老 发表于 2021/07/26 22:53:52 2021/07/26
【摘要】 本文目录 前言AnimatedWidgetAnimatedBuilder 前言 在上一篇的动画内容中,我们学习了基本的概念,以及动画的基本使用规则,但是,上一篇的代码真的实际项目中应用很多吗?其实不是,上一篇之所以那么介绍,只是为了让大家更了解Flutter动画的原理,其实还有更简单封装与简化的使用方式,这一篇就开始学习这些内容。 Animated...

前言

在上一篇的动画内容中,我们学习了基本的概念,以及动画的基本使用规则,但是,上一篇的代码真的实际项目中应用很多吗?其实不是,上一篇之所以那么介绍,只是为了让大家更了解Flutter动画的原理,其实还有更简单封装与简化的使用方式,这一篇就开始学习这些内容。

AnimatedWidget

前面动画之中,我们都是通过addListener和setState来更新UI的,然而有时候可以不用这么麻烦,通过AnimationWidget这个类就可以实现,它对addListener和setState进行了封装,隐藏了实现细节。下面,我们直接上代码来看看:

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
  Animation<double> animation;
  AnimationController controller; initState(){ super.initState(); controller=AnimationController(duration: const Duration(milliseconds: 2000),vsync: this); animation=CurvedAnimation(parent: controller,curve: Curves.bounceIn)..addStatusListener((status){ if(status==AnimationStatus.completed){//动画在结束时停止的状态 controller.reverse();//颠倒 }else if(status==AnimationStatus.dismissed){//动画在开始时就停止的状态 controller.forward();//向前 } })..addListener((){ setState(() { print(animation.value); }); }); controller.forward();
  } @override
  void dispose() { controller.dispose(); // TODO: implement dispose super.dispose();
  } @override
  Widget build(BuildContext context) { return AnimationLogo(animation: animation,);
  }
}

class AnimationLogo extends AnimatedWidget{ AnimationLogo({Key key,Animation<double> animation}) :super(key:key,listenable:animation); @override
  Widget build(BuildContext context) { final Animation<double> animation=listenable; return Scaffold( appBar: AppBar( title: Text("封装动画"), ), body: Container( height: animation.value*300, margin: EdgeInsets.symmetric(vertical: 10.0), width: animation.value*300, child: FlutterLogo(), ), );
  }

}
  
 

封装后,AnimationLogo可以通过当前自身Animation的value值来绘制自己。

AnimatedBuilder

有时候我们会使用多个AnimatedWidget,而如果多次实现AnimatedWidget,则代码就显得不那么美观了,这个时候,我们就需要考虑使用AnimatedBuilder,它的优点有:

(1)不需要知道如何渲染组件,也不需要知道如何管理动画对象

(2)继承自AnimatedWidget,可以直接当作组件来使用,且不用显式地去添加帧的监听addListener(…),然后在调用setState

(3)只调用动画组件中地build,在复杂地布局下性能有所提高

我们先来看一张组件示意图:

组件
接着我们将上面的代码进行重构,代码如下:

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
  Animation<double> animation;
  AnimationController controller; initState(){ super.initState(); controller=AnimationController(duration: const Duration(milliseconds: 2000),vsync: this); animation=CurvedAnimation(parent: controller,curve: Curves.bounceIn)..addStatusListener((status){ if(status==AnimationStatus.completed){//动画在结束时停止的状态 controller.reverse();//颠倒 }else if(status==AnimationStatus.dismissed){//动画在开始时就停止的状态 controller.forward();//向前 } })..addListener((){ setState(() { }); }); controller.forward();
  } @override
  void dispose() { controller.dispose(); // TODO: implement dispose super.dispose();
  } @override
  Widget build(BuildContext context) { return GrowTransition(child:AnimationLogo(),animation: animation,);
  }
}

class AnimationLogo extends StatelessWidget{
  @override
  Widget build(BuildContext context) { // TODO: implement build return Container( margin: EdgeInsets.symmetric(vertical: 10), child: FlutterLogo(), );
  }
}

class GrowTransition extends StatelessWidget{
  final Widget child;
  final Animation<double> animation;
  GrowTransition({this.child,this.animation});
  @override
  Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("AnimatedBuilder"),), body: Center( child: AnimatedBuilder( animation: this.animation, builder: (BuildContext context,Widget child){ return Container( height: animation.value*300, width: animation.value*300, child: child, ); }, child: this.child, ), ), );
  }
}

  
 

前面的代码基本一样,就是后面的代码变更了,所以重点看后面的代码就行。其实在Flutter开发中,通过AnimatedBuilder方式还封装了很多动画,比如SizeTransition,ScaleTransition,RotationTransition,FadeTransition,FractionalTranslation等。很多时候我们都可以反复使用这些预置的过渡类。效果图更前篇文章差不多,这里就不展示了。

文章来源: liyuanjinglyj.blog.csdn.net,作者:李元静,版权归原作者所有,如需转载,请联系作者。

原文链接:liyuanjinglyj.blog.csdn.net/article/details/104136939

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。