文章目录

  • 1 概述
  • 2 Animation
  • 3 AnimationController
  • 4 Curve
  • 5 Tween
  • 6 示例
    • 6.1 示例1-ColorTween使用
    • 6.2 示例2-自定义AnimatedWidget
    • 6.3 示例3-Curves使用
    • 6.4 示例4-3D效果
    • 6.5 示例5-卡片翻转效果
    • 6.6 示例6

1 概述

Flutter中的动画分为补间(Tween)动画和基于物理(Physics-based)的动画。

  • 在补间动画中,定义了开始点和结束点、时间线以及定义转换时间和速度的曲线,然后由框架自动计算如何从开始点过渡到结束点。
  • 在基于物理的动画(遵循物理学定律)中,运动被模拟为与真实世界的行为相似,可以模拟弹簧、阻尼、重力等物理效果。例如,当你掷球时,它在何处落地,取决于抛球速度有多快、球有多重、距离地面有多远。类似地,将连接在弹簧上的球落下(并弹起)与连接到绳子上的球放下的方式也是不同。

2 Animation

四种状态:

  • dismissed:动画初始状态
  • forward:动画从头到尾播放状态
  • reverse:动画从尾到头播放状态
  • completed:动画完成状态

Animation类是Flutter动画中核心的抽象类,它包含动画的当前值和状态两个属性。定义了动画的一系列监听回调。

  • 值监听:addListener、removeListener
  • 状态监听:addStatusListener、removeStatusListener

3 AnimationController

动画的控制。

  • AnimationController是一个特殊的Animation对象,在屏幕刷新的每一帧,就会生成一个新的值,默认情况下,AnimationController在给定的时间段内会线性的生成从0.0到1.0的数字
  • 属于Animation类型
  • 具有控制动画的方法,例如,.forward()方法可以启动动画
  • 当创建一个AnimationController时,需要传递一个vsync参数,存在vsync时会防止屏幕外动画(动画的UI不在当前屏幕时)消耗不必要的资源。
  • 通过将SingleTickerProviderStateMixin添加到类定义中,可以将stateful对象作为vsync的值。如果要使用自定义的State对象作为vsync时,请包含TickerProviderStateMixin。
  • 特别注意:在不使用时需要调用dispose方法,否则会造成资源泄露

4 Curve

定义了时间和数值的抽象类。Flutter封装定义了一系列的插值器,如linear、decelerate、ease、bounce、cubic等。当然Flutter提供的不满足需求的话,也可以自定义插值器。

5 Tween

线性估值器。Flutter还封装定义了不同类型的估值器:

  • ReverseTween
  • ColorTween
  • SizeTween
  • RectTween
  • IntTween
  • StepTween
  • ConstantTween

6 示例

6.1 示例1-ColorTween使用

实现背景颜色的渐变效果:

import 'package:flutter/material.dart';void main() => runApp(MaterialApp(home: HomePage(),));class HomePage extends StatefulWidget {@override_HomePageState createState() => _HomePageState();
}class _HomePageState extends State<HomePage>with SingleTickerProviderStateMixin {Animation<Color> _doubleAnim;AnimationController _animationController;//四种状态//1 dismissed 初始状态//2 forward 从头到尾播放状态//3 reverse 从尾到头播放状态//4 completed 完成状态@overridevoid initState() {super.initState();_animationController =AnimationController(vsync: this, duration: const Duration(seconds: 1))..forward();_doubleAnim = ColorTween(begin: Colors.red, end: Colors.white).animate(_animationController)..addListener(() {setState(() {});})..addStatusListener((status) {if (status == AnimationStatus.completed) {_animationController.reverse();} else if (status == AnimationStatus.dismissed) {_animationController.forward();}});
//    _animationController.forward();}@overridevoid dispose() {super.dispose();_animationController.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Container(width: 200.0,height: 200.0,color: _doubleAnim.value,child: FlutterLogo(),),),floatingActionButton: FloatingActionButton(onPressed: null),);}
}

效果如下:

6.2 示例2-自定义AnimatedWidget

实现旋转和放大缩小效果:

import 'package:flutter/material.dart';void main() => runApp(MaterialApp(home: HomePage(),));class HomePage extends StatefulWidget {@override_HomePageState createState() => _HomePageState();
}class _HomePageState extends State<HomePage>with SingleTickerProviderStateMixin {Animation<double> _doubleAnim;AnimationController _animationController;@overridevoid initState() {super.initState();_animationController =AnimationController(vsync: this, duration: const Duration(seconds: 1))..forward();_doubleAnim = Tween(begin: 0.0, end: 1.0).animate(_animationController)..addListener(() {setState(() {});})..addStatusListener((status) {if (status == AnimationStatus.completed) {_animationController.reverse();} else if (status == AnimationStatus.dismissed) {_animationController.forward();}});}@overridevoid dispose() {super.dispose();_animationController.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: MyLogo(animation: _doubleAnim,),),);}
}class MyLogo extends AnimatedWidget {final Tween<double> _rotateAnim = Tween<double>(begin: 0.0, end: 20.0);final Tween<double> _scaleAnim = Tween<double>(begin: 1.0, end: 10.0);
//  final Tween<Color> _colorAnim = Tween<Color>(begin: Colors.white, end: Colors.red);MyLogo({Key key, @required Animation animation}): super(key: key, listenable: animation);@overrideWidget build(BuildContext context) {final Animation<double> animation = listenable;return Transform.scale(scale: _scaleAnim.evaluate(animation),child: Transform.rotate(angle: _rotateAnim.evaluate(animation),child: Container(child: FlutterLogo(),),),);}
}

6.3 示例3-Curves使用

import 'package:flutter/material.dart';void main() => runApp(MaterialApp(home: HomePage(),));class HomePage extends StatefulWidget {@override_HomePageState createState() => _HomePageState();
}class _HomePageState extends State<HomePage>with SingleTickerProviderStateMixin {Animation<double> _doubleAnim;AnimationController _animationController;void myListener(status) {if (status == AnimationStatus.completed) {_animationController.removeStatusListener(myListener);_animationController.reset();_doubleAnim = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: _animationController, curve: Curves.fastOutSlowIn));_animationController.forward();}}@overridevoid initState() {super.initState();_animationController =AnimationController(vsync: this, duration: const Duration(seconds: 2));_doubleAnim = Tween(begin: -1.0, end: 0.0).animate(CurvedAnimation(parent: _animationController, curve: Curves.fastOutSlowIn))..addStatusListener(myListener);_animationController.forward();}@overridevoid dispose() {super.dispose();_animationController.dispose();}@overrideWidget build(BuildContext context) {var _screenWidth = MediaQuery.of(context).size.width;return Scaffold(body: AnimatedBuilder(animation: _animationController,builder: (BuildContext context, Widget child) {return Transform(transform: Matrix4.translationValues(_doubleAnim.value * _screenWidth, 0.0, 0.0),child: Center(child: Container(width: 200.0,height: 200.0,child: FlutterLogo(),),),);}),);}
}

6.4 示例4-3D效果

import 'package:flutter/material.dart';void main() => runApp(MaterialApp(home: HomePage(),));class HomePage extends StatefulWidget {@override_HomePageState createState() => _HomePageState();
}class _HomePageState extends State<HomePage> {Offset _offset = Offset.zero;@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Transform(transform: Matrix4.identity()..setEntry(3, 2, 0.001)..rotateX(_offset.dy * 0.01)..rotateY(_offset.dx * 0.01),child: GestureDetector(onPanUpdate: (details) {setState(() {_offset += details.delta;//更新offset(point)});},onDoubleTap: () {setState(() {_offset = Offset.zero;});},child: Container(width: 200.0,height: 200.0,color: Color(0xffff0000),),),),),);}
}

6.5 示例5-卡片翻转效果

import 'dart:math';import 'package:flutter/material.dart';void main() => runApp(MaterialApp(home: HomePage(),));class HomePage extends StatefulWidget {@override_HomePageState createState() => _HomePageState();
}class _HomePageState extends State<HomePage>with SingleTickerProviderStateMixin {Animation<double> _animation;AnimationController _animationController;bool reversed = false;@overridevoid initState() {super.initState();_animationController =AnimationController(vsync: this, duration: Duration(seconds: 1));_animation = TweenSequence([TweenSequenceItem(tween: Tween(begin: 0.0, end: -pi / 2),weight: 0.5,),TweenSequenceItem(tween: Tween(begin: pi / 2, end: 0.0),weight: 0.5,),]).animate(_animationController);}@overridevoid dispose() {super.dispose();_animationController.dispose();}_doAnim() {reversed ? _animationController.reverse() : _animationController.forward();reversed = !reversed;}@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: AnimatedBuilder(animation: _animation,builder: (BuildContext context, Widget child) {return Transform(transform: Matrix4.identity()..setEntry(3, 2, 0.001)..rotateY(_animation.value),alignment: Alignment.center,child: GestureDetector(onTap: _doAnim,child: IndexedStack(children: <Widget>[CardOne(),CardTwo(),],alignment: Alignment.center,index: _animationController.value < 0.5 ? 0 : 1,//0~1),),);}),),);}
}class CardOne extends StatelessWidget {@overrideWidget build(BuildContext context) {return Card(color: Color(0xffff0000),child: Container(width: 200.0,height: 200.0,child: Text('点我看密码',style: TextStyle(color: Color(0xffffffff), fontSize: 30.0),),),);}
}class CardTwo extends StatelessWidget {@overrideWidget build(BuildContext context) {return Card(color: Color(0xff0000ff),child: Container(width: 200.0,height: 200.0,child: Text('123456',style: TextStyle(color: Color(0xffffffff), fontSize: 30.0),),),);}
}

6.6 示例6

import 'dart:math';import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: HomePage(),);}
}class HomePage extends StatefulWidget {@override_HomePageState createState() => _HomePageState();
}class _HomePageState extends State<HomePage>with SingleTickerProviderStateMixin {Tween<double> _tween;AnimationController _animationController;@overridevoid initState() {super.initState();_animationController =AnimationController(vsync: this, duration: Duration(seconds: 5))..repeat();_tween = Tween<double>(begin: 0.0, end: 1.0);}Animation get animOne => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.0,0.125,curve: Curves.linear,),),);Animation get animTwo => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.125,0.25,curve: Curves.linear,),),);Animation get animThree => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.25,0.375,curve: Curves.linear,),),);Animation get animFour => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.375,0.5,curve: Curves.linear,),),);Animation get animFive => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.5,0.625,curve: Curves.linear,),),);Animation get animSix => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.625,0.75,curve: Curves.linear,),),);Animation get animSeven => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.75,0.875,curve: Curves.linear,),),);Animation get animEight => _tween.animate(CurvedAnimation(parent: _animationController,curve: Interval(0.875,1.0,curve: Curves.linear,),),);@overridevoid dispose() {super.dispose();_animationController.dispose();}@overrideWidget build(BuildContext context) {final screenWidth = MediaQuery.of(context).size.width;return Scaffold(body: Center(child: Row(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[new AnimatedBrick(animations: [animOne, animTwo],controller: _animationController,marginLeft: 0.0,alignment: Alignment.centerLeft,isClockWise: true,),new AnimatedBrick(animations: [animThree, animEight],controller: _animationController,marginLeft: 0.0,isClockWise: false,),new AnimatedBrick(animations: [animFour, animSeven],controller: _animationController,marginLeft: 30.0,isClockWise: true,),new AnimatedBrick(animations: [animFive, animSix],controller: _animationController,marginLeft: 30.0,isClockWise: false,),],),),);}
}class AnimatedBrick extends AnimatedWidget {final AnimationController controller;final List<Animation> animations;final double marginLeft;final Alignment alignment;final bool isClockWise;AnimatedBrick({Key key,this.controller,this.animations,this.marginLeft,this.alignment = Alignment.centerRight,this.isClockWise,}) : super(key: key, listenable: controller);Matrix4 clockWise(animation) =>Matrix4.rotationZ(animation.value * pi * 2.0 * 0.5);Matrix4 antiClockWise(animation) =>Matrix4.rotationZ(-(animation.value * pi * 2.0 * 0.5));@overrideWidget build(BuildContext context) {var firstTransformation =isClockWise ? clockWise(animations[0]) : antiClockWise(animations[0]);var secondTransformation =isClockWise ? clockWise(animations[1]) : antiClockWise(animations[1]);return Transform(alignment: alignment,transform: firstTransformation,child: Transform(alignment: alignment,transform: secondTransformation,child: BrickWidget(marginLeft: marginLeft)));}
}class BrickWidget extends StatelessWidget {final double marginLeft;const BrickWidget({Key key,this.marginLeft = 15.0,}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(margin: EdgeInsets.only(left: marginLeft),width: 40.0,height: 10.0,decoration: BoxDecoration(borderRadius: BorderRadius.circular(15.0),color: Color(0xffff0000),),);}
}

Flutter 动画篇相关推荐

  1. 【Flutter】Animation 动画 ( Flutter 动画基本流程 | 创建动画控制器 | 创建动画 | 设置值监听器 | 设置状态监听器 | 布局中使用动画值 | 动画运行 )

    文章目录 一.创建动画控制器 二.创建动画 三.设置值监听器 四.设置状态监听器 五.布局中使用动画值 六.动画运行 七.完整代码示例 八.相关资源 Flutter 动画基本流程 : ① 创建动画控制 ...

  2. 【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )

    文章目录 一.动画的核心类 Animation 二.动画的核心类 CurvedAnimation 三.动画的核心类 AnimationController 四.动画的核心类 Tween 五.相关资源 ...

  3. 【Flutter】Animation 动画 ( Flutter 动画类型 | Flutter 动画的核心类 )

    文章目录 一.Flutter 动画类型 二.Flutter 动画的核心类 三.相关资源 Flutter Animation 动画 : Flutter 动画类型 为 Widget 组件添加动画 为动画添 ...

  4. 转:Flutter动画一

    1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才会觉得炫酷.移动端的动画库有非常的多,例如iOS上的Pop.web端的animate.css.Android端的An ...

  5. 学习笔记-Flutter 动画详解(一)

    Flutter 动画详解(一) 本文主要介绍了动画的原理相关概念,对其他平台的动画做了一个简要的梳理,并简要的介绍了Flutter动画的一些知识. 1. 动画介绍 动画对于App来说,非常的重要.很多 ...

  6. flutter 动画展开菜单_Flutter 动画详解(一)

    本文主要介绍了动画的原理相关概念,对其他平台的动画做了一个简要的梳理,并简要的介绍了Flutter动画的一些知识. 1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才 ...

  7. 史上最详细Flutter 动画讲解

    1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才会觉得炫酷.移动端的动画库有非常的多,例如iOS上的Pop.web端的animate.css.Android端的An ...

  8. flutter 点击旋转动画_让动画实现更简单,Flutter 动画简易教程!

    Flutter中的动画功能强大且易于使用.接下来通过一个具体的实例,您将学到关于 Flutter 动画的一切. 难度:中级 今天,我们无法想象移动应用程序里面没有任何动画,当您从一页跳转到另一页时,或 ...

  9. Android源码解析(一)动画篇-- Animator属性动画系统

    Android源码解析-动画篇 Android源码解析(一)动画篇-- Animator属性动画系统 Android源码解析(二)动画篇-- ObjectAnimator Android在3.0版本中 ...

最新文章

  1. 深入浅出统计学(十一)总体和样本的估计
  2. 一个项目从开工到交付使用需要经历的过程
  3. 黑马2016java_2016年成功的Java开发人员简介
  4. 笔记本(华硕UL80VT)软件超频setFSB
  5. php coder 乱码,MySQL 乱码 与 字符集
  6. 将windows c盘安装在linux,将WindowsC盘hda1安装在Linux文件系统的/winsys目录下,命令是()。...
  7. Python成长之路第一篇(1)__字符串初识
  8. 我的世界服务器起床地图维修,Minecraft·起床战争地图更新来了!地图“雪仗”全面解读!...
  9. cad卸载_CAD卸载不干净,如何清理CAD注册表
  10. 详细介绍ADMM交替方向乘子法
  11. Python编程从入门到实践(第2版)个人学习笔记
  12. 春招面试阿里,面试官让我说说Java8的新特性
  13. GitHub上最火的两份Java面试小册,Star已经超百万
  14. 代码生成器的使用步骤
  15. 两步实现在网站左下角实现音乐播放器弹窗听歌
  16. 锐雅中国集团公司怎么样?
  17. RecyclerView的使用(二)——拖曳移动和滑动删除
  18. Karma与TSLint
  19. 在Excel中批量下载网络图片,存放到右方单元格或插入到批注,#excel插件
  20. 医疗物联网平台架构图

热门文章

  1. Could not transfer artifact (https://repo.maven.apache.org/maven2): Received fatal alert: protocol_v
  2. 有多远滚多远 html5游戏,68微信游戏有多远滚多远怎样能得高分
  3. 计算机的优缺点英语作文100词,英语作文 电脑的优点和缺点_900字_英语作文
  4. 使用Plumber和React缩放R
  5. 计算机专业可以转行医学吗,医学,会计,
  6. 阶乘因式分解(二) nyist
  7. 火猴之ppt动画效果实现(firemonkey)
  8. warning: unused variable ‘D‘ [-Wunused-variable]|
  9. 微信公众号支付问题 - 当前页面的URL未注册
  10. 后台弹出页面或模式窗口