当前位置:   article > 正文

Flutter的隐式动画详解_flutter 动画效果

flutter 动画效果

目录

前言

一、AnimatedOpacity

二、AnimatedPadding

三、AnimatedPositioned

四、AnimatedSwitcher

五、AnimatedAlign

六、AnimatedContainer

七、AnimatedBuilder

八、AnimatedSize

总结


前言

        Flutter中的隐式动画指的是通过使用Flutter的动画库,就可以创建各种炫酷的UI视觉效果。 我们可以使用库中的一套组件来管理动画,这些组件被称为隐式动画组件。隐式动画组件都实现了ImplicitlyAnimatedWidget类,这些隐式动画组件有个共同的特点就是组件都以Aanimated为前缀。使用隐式动画,我们只需要关注动画的初始值和最终值,而不需要做额外的处理,这给我们的工作带来了很大的方便。

        这里写了一个效果图,先通过小面的效果图看下隐式动画能实现哪些炫酷的UI视觉效果,然后在看看Flutter中常用的隐式动画组件。

        

图1.AnimatedWidget动画效果

一、AnimatedOpacity

        opacity即透明度,我们可以通过修改Widget的opacity值来实现动画的效果。可以看下图1实力中的第一个动画效果。这里随机生成了一个Container组件,然后每隔0.25s修改下Container的透明度。这里我们通过官方的文档来实现渐如效果。

        AnimatedWidget的用法和Widget的用法基本相同,我们只需关注AnimatedWidget实现的ImplicitlyAnimatedWidget即可。

        我们以下面的效果为例,看下AnimatedOpacity的用法。

        图2.点击按钮显示图片详情

        在图2中,我们点击显示图片简介的时候,显示图片的详细信息。点击隐藏的时候,隐藏图片的信息。关键代码如下:

  1. class _MyHomePageState extends State<MyHomePage> {
  2. double opacity = 0;
  3. bool showDetail = false;
  4. @override
  5. Widget build(BuildContext context) {
  6. return Scaffold(
  7. appBar: AppBar(
  8. backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  9. title: Text(widget.title),
  10. ),
  11. body: Center(
  12. // Center is a layout widget. It takes a single child and positions it
  13. // in the middle of the parent.
  14. child: Column(children: <Widget>[
  15. const Image(image: AssetImage('images/opacity.png'),width: 480,height: 270,),
  16. TextButton(
  17. child: Text(
  18. opacity == 0 ?'显示图片简介':'隐藏图片简介',
  19. style: const TextStyle(color: Colors.blueAccent),
  20. ),
  21. onPressed: () => setState(() {
  22. if(opacity == 0){
  23. opacity = 1;
  24. }else{
  25. opacity = 0;
  26. }
  27. }),
  28. ),
  29. opacity ==0 ? const SizedBox():const Column(
  30. children: [
  31. Text('图片作者: 柱子哥',),
  32. Text('图片拍摄地点: 上海'),
  33. Text('图片分辨率: 480 * 270'),
  34. ],
  35. )
  36. ]),
  37. ), // This trailing comma makes auto-formatting nicer for build methods.
  38. );
  39. }
  40. }

       上述的代码非常简单,我们通过一个标记为来控制图片信息的显示和隐藏。显示的视觉鲜果没有动画,稍微显得有点生硬,我们看一下如何给图片简介信息添加动画效果。当我们点击显示图片简介信息的时候,1秒种之后,简介信息的透明度从0到1逐渐变化。这个时候AnimatedOpactity就派上了用场。

        AnimatedOpactity的用法也很简单,我们只需要把要处理的Widget包裹起来即可。

        这里我们只需要AanimatedOpacity的opacity属性和duration属性。AnimatedOpacity会根据我们设置的参数自动处理动画。再上述的demo中,我们把标志位设置为AnimatedOpacity的opacity属性,duration设置为1s,就会产生一个动画效果。效果图如下:

             图3.AnimatedOpacity动画效果

        我们看一下AnimatedOpacity的定义:

const AnimatedOpacity({
super.key,
this.child,
required this.opacity,
super.curve,
required super.duration,
super.onEnd,
this.alwaysIncludeSemantics = false,
}) : assert(opacity >= 0.0 && opacity <= 1.0);

        我们还可以通过curve属性定义动画变化的曲线,默认是Curves.linear(线性动画),设置onEnd来配置动画完成之后的回调函数。

二、AnimatedPadding

        AnimatedPadding和Padding用法大致相同,我们可以通过改变padding属性,移动Widget,达到动画的效果。

        这里有两个属性padding和duration。其中padding为间距,duration为动画时长。下面的例子中,我们通过一个定时器,不断的修改padding属性,做了一个闪光灯的效果。

        图4.粗糙的闪光灯效果

三、AnimatedPositioned

        AnimatedPositioned动画就是通过修改Positon的top,bottom,left,right属性来修改Widget的位置,产生一个动画效果。这里AanimatedPositioned的用法和AnimatedPadding用法类似,这里就不做赘述了。下面也写了一个动画效果,点击移动小球之后,小球每次左移50个单位。

        

图5.AnimatedPositioned动画

四、AnimatedSwitcher

        AnimatedSwitcher用来切换两个不同的组件。

        这里需要注意的是当我们切换组件的时候,我们需要为旧的组件和新的Widget设置一个不同的key,动画效果才会生效。这种动画应用也挺广泛的,例如我们在使用微信和支付宝付款的时候,付款完成之后就会有一个完成的动画。


图6.AnimatedSwitcher动画效果

关键代码如下:

  1. class _MyHomePageState extends State<MyHomePage> {
  2. bool isCompleted = false;
  3. int keyValue = 0;
  4. Widget completedWidget(){
  5. return GestureDetector(
  6. key: ValueKey<int>(keyValue),
  7. child: Container(
  8. width: 100,
  9. height: 40,
  10. alignment: Alignment.center,
  11. decoration: const BoxDecoration(
  12. color: Colors.black12,
  13. borderRadius: BorderRadius.all(Radius.circular(20))
  14. ),
  15. child: const Text('点击完成',style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold),),
  16. ),
  17. onTap: (){
  18. setState(() {
  19. keyValue++;
  20. isCompleted = !isCompleted;
  21. });
  22. },
  23. );
  24. }
  25. Widget normalWidget(){
  26. return GestureDetector(
  27. key: ValueKey<int>(keyValue),
  28. child: Container(
  29. width: 50,
  30. height: 50,
  31. alignment: Alignment.center,
  32. decoration: const BoxDecoration(
  33. color: Colors.green,
  34. borderRadius: BorderRadius.all(Radius.circular(25))
  35. ),
  36. child: const Icon(Icons.check),
  37. ),
  38. onTap: (){
  39. setState(() {
  40. keyValue++;
  41. isCompleted = !isCompleted;
  42. });
  43. },
  44. );
  45. }
  46. @override
  47. Widget build(BuildContext context) {
  48. return Scaffold(
  49. appBar: AppBar(
  50. backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  51. title: Text(widget.title),
  52. ),
  53. body: Center(
  54. child: Column(
  55. mainAxisAlignment: MainAxisAlignment.center,
  56. children: <Widget>[
  57. AnimatedSwitcher(
  58. duration: const Duration(milliseconds: 2000),
  59. child: isCompleted?completedWidget():normalWidget(),
  60. ),
  61. ],
  62. ),
  63. ), // This trailing comma makes auto-formatting nicer for build methods.
  64. );
  65. }
  66. }

五、AnimatedAlign

        AnimatedAlign通过修改子类Widget的位置实现UI动画效果。用法也比较简单,这里也写了一个小球移动类似于贪吃蛇的效果。效果图如下,我们结合一个计时器不停的修改AnimatedAlign的padding即可。

图7.AnimatedAlign动画效果

六、AnimatedContainer

        Flutter中的Container是一个容器,有着非常多的属性,因此我们可以使用AnimatedContainer可以实现非常多的动画效果。

        例如下面这个来自官网的例子中,我们可以修改Widget和颜色和圆角,实现Widget形状的变化动画效果。

图8.AnimatedContainer实现的各种动画效果

七、AnimatedBuilder

        上面的AnimatedWidget实现的动画效果我们都是通过设置参数来实现的,当然我们也可以自定义动画效果。这个时候AnimatedBuilder就派上用场了。例如我们要实现一个如下图所示的Widget的旋转动画效果。

图9.AnimatedBuilder动画效果

       在使用AnimatedBuilder的时候,有两个参数,animation和builder。

        其中animation用来定义动画的类型

        builder是一个回调函数,在回调函数中我们配置要做动画的Widget和使用的动画类型。

        当然这里如果要使用AnimatedBuilder要继承自SingleTickerProviderStateMixin。

        主要的代码如下:

  1. class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  2. late Animation<num> animation ;
  3. late AnimationController controller;
  4. @override
  5. void initState() {
  6. super.initState();
  7. controller = AnimationController(
  8. duration: const Duration(seconds: 4),
  9. vsync: this)..repeat();
  10. animation = Tween(begin: 0,end: 2 * pi).animate(controller);
  11. }
  12. @override
  13. Widget build(BuildContext context) {
  14. return Scaffold(
  15. appBar: AppBar(
  16. backgroundColor: Theme.of(context).colorScheme.inversePrimary,
  17. title: Text(widget.title),
  18. ),
  19. body: Center(
  20. child: Container(
  21. alignment: Alignment.center,
  22. child: AnimatedBuilder(animation: animation, builder: (BuildContext context, Widget? child) {
  23. return Transform.rotate(
  24. angle: animation.value.toDouble(),
  25. child: Container(
  26. color: Colors.deepOrange,
  27. width: 200,
  28. height: 200,
  29. alignment: Alignment.center,
  30. child: const Text('AnimatedBuilder动画',style: TextStyle(fontSize: 14,fontWeight: FontWeight.bold,),textAlign: TextAlign.center,),
  31. ),
  32. );
  33. },
  34. ),
  35. ),
  36. ), // This trailing comma makes auto-formatting nicer for build methods.
  37. );
  38. }
  39. }

八、AnimatedSize

        AnimatedSize可以通过修改width和height属性实现动画效果。

        例如下面的UI动画效果,我们点击按钮的时候,Widget的高度和宽度都增加50,这样就实现了放大的动画效果。

        

图10.AnimatedSize动画效果

总结

        隐式动画写到这里,基本上也差不多了,总结下AnimatedWidget的用法和Widget基本相似,我们只需要关注AnimatedWidget的旧的属性值和新的属性值,然后通过配置参数就可以实现各种酷炫的UI视觉效果,当然我们可以通过AnimatedBuilder来实现动画的自定义。更多的AnimatedWidget的用法以后再更新吧。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/257370
推荐阅读
相关标签
  

闽ICP备14008679号