flutter动画入门

对于前端来说,我感觉最大的魅力就是在于动画效果了;最初入坑前端就是想做出炫酷的动画,其实可以学习AE什么的,当时不懂,就入了前端程序员的坑。当然用代码实现出炫酷的动画效果,更会让自己充满成就感。

封面.gif

1. 动画简介

在一段时间内,快速地多次改变UI外观,由于人眼会产生视觉残留,所以最后会看到连续的动画。对于人眼来说,动画帧率超过16FPS,就比较流畅了,超过32FPS就会非常的细腻平滑,而超过32FPS,人眼基本上就感受不到差别了。由于动画的每一帧都是要改变UI输出,所以在一个时间段内连续的改变UI输出是比较耗资源的,对设备的软硬件系统要求都较高,所以在UI系统中,动画的平均帧率是重要的性能指标,而在Flutter中,理想情况下是可以实现60FPS的,这和原生应用能达到的帧率是基本是持平的。—— 《flutter实战.动画简介》

2. flutter动画

在web前端,我们实现动画可以通过css过渡元素,定义css关键帧,js等定义动画函数等方式去实现,那么flutter如何去实现动画效果呢?如果是想简单的实现动画,可以选择flutter内置的一些动画Widget,flutter已经封装好了:AnimatedPaddingAnimatedPositionedAnimatedOpacityAnimatedAlignAnimatedContainerAnimatedDefaultTextStyle,这些拿来即用,但是这些不能随心控制;想要自己自定义实现动画的话那就需要以下的几个步骤:

  • 创建一个动画控制器AnimationController
  • 添加一个描述动画的过程Curve,返回的是一个Animation
  • 添加tween,控制动画的执行范围,需要执行animate方法,返回Animation
    AnimationController: 创建动画控制器,默认动画执行范围是[0,1],如果需要改变的话,需要用到tween

3. 开始制作简单的动画

动画效果:一个正方形,先变大,然后变颜色,然后再变小,还原颜色
前提准备,新建好项目,新建class AnimationDemo

class AnimationDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return AnimationDemoState();
  }
}

class AnimationDemostate extends State<AnimationDemo> with SingleTickerProviderStateMixin {
  // SingleTickerProviderStateMixin 性能有关,需要执行Ticker
  // 动画控制器需要传这个参数,效果是在页面不可见的区域,动画不会执行,避免消耗资源。
}
3.1 定义动画和控制器变量
class AnimationDemostate extends State<AnimationDemo> with SingleTickerProviderStateMixin {
  // SingleTickerProviderStateMixin 性能有关,需要执行Ticker
  // 动画控制器需要传这个参数,效果是在页面不可见的区域,动画不会执行,避免消耗资源。
Animation animation;
AnimationController _animationController;
}
3.2 初始化动画变量

我们先尝试让红色的正方形在3秒内从10的宽高变道300的宽高,以下代码中做了以下几步

  1. 先创建了一个动画控制器,duration动画的持续时间,vsync这个就是当前的State
  2. 创建了一个动画函数CurvedAnimation它的是一个Animation
  3. 创建Tween,begin:10.0,end: 300.0,这个就是在3秒之内会生成10~300的值
    new Tween它是继承Animatable<T>,而不是跟CurvedAnimation一样继承Animation;那我们创建的Animatable如何与Animation形成映射呢?答案是执行animate方法把Animation传进去,就形成了新的Animation,我们就可以在Widget中愉快使用了它了。
  4. 执行动画 _animationController.forward();
class AnimationDemostate extends State<AnimationDemo> with SingleTickerProviderStateMixin{
  ···
   @override
  void initState() {
    // TODO: implement initState
    _animationController = new AnimationController(
      duration: Duration(seconds: 3),
      vsync: this,
    );
    animation = new CurvedAnimation(
      parent: _animationController,
      curve: Curves.ease
    );
    // Tween begin,end 就是大小变化的区间
    animationSize = new Tween(begin: 10.0, end: 300.0).animate(animation)
      ..addListener((){
        setState(() {
          
        });
      });
    
    _animationController.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        ···
          new Container(
            width: animationSize.value,
            height: animationSize.value,
            decoration: BoxDecoration(
              color: Colors.red,
            ),
          )
        ···
    )
  }
  ···
}

经过上面步骤之后我们来看下效果:


红色正方形变大.gif

皆大欢喜,我们已经成功了第一步!能有动画的效果了,我们继续深入后续的步骤

3.3 让红色正方形变大的过程中变成其他颜色

这种相当于是关键帧的意思,就是先变大,在变大的过程中某个时间开始变颜色;在web中我们知道css中有@keyframe可是设置关键帧,来进行交织动画,flutter中我们如何实现呢?
在3.2步骤中我们创建过一个动画曲线CurvedAnimationcurve传的是flutter内置的动画函数Curves.ease,在vscode中打出Curves后编辑器会有提示所有的内置的函数;我们要打关键帧的话,关键在于此curve,这里需要用到Interval(start, end),这个Interval通过start和end我们就能知道了,它表示的是一段时间间隔,可以传入curve参数。
了解上面的内容之后,我们思路应该清爽了,那继续深入

3.3.1 使正方形变大的过程中由红色变成蓝色
class xxx extends xxx with xxx {
  // 定义变量
  Animation animationColor;
  // 初始化变量
  void initState() {
     // TODO: implement initState
    _animationController = new AnimationController(
      duration: Duration(seconds: 3),
      vsync: this,
    );
    animation = new CurvedAnimation(
      parent: _animationController,
      curve: new Interval(0, 0.5) // 这里执行间隔 是3秒中0~50%的时间执行正方形变大,默认动画
    );
    animationSize = new Tween(begin: 10.0, end: 300.0).animate(animation)
      ..addListener((){
        setState(() {
          
        });
      });
    animation = new CurvedAnimation(
      parent: _animationController,
      curve: new Interval(0.5, 1.0, curve: Curves.easeIn) // 50%~100%执行变颜色,并且动画是easeIn
    );
    animationColor = new ColorTween(begin: Colors.white, end: Colors.blue).animate(animation)
      ..addListener((){
        setState(() {
          
        });
      });
  }
}

通过上面步骤之后
我们来看看最终的的效果:


红色正方形动画.gif

最后想实现循环往复的效果

需要在动画监听状态中去改变动画的方向就可以了
方法如下:

animation.addStatusListener((status){
      if (status == AnimationStatus.completed) {
          _animationController.reverse();
        } else if (status == AnimationStatus.dismissed) {
          _animationController.forward();
        }
      });

来看看效果:


最终效果.gif

总结

这边主要是对flutter动画的一个简单的入门,按照上面步骤一步步的去实现flutter的动画,应该就会对flutter动画有了一定的了解了,具体深入的了解可以看官方文档和其他资料的书籍,如果文中有讲述不到位的地方,或者有错误的地方,也请大佬们多多指教,康桑密达!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349