Flutter 动画篇
文章目录
- 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 动画篇相关推荐
- 【Flutter】Animation 动画 ( Flutter 动画基本流程 | 创建动画控制器 | 创建动画 | 设置值监听器 | 设置状态监听器 | 布局中使用动画值 | 动画运行 )
文章目录 一.创建动画控制器 二.创建动画 三.设置值监听器 四.设置状态监听器 五.布局中使用动画值 六.动画运行 七.完整代码示例 八.相关资源 Flutter 动画基本流程 : ① 创建动画控制 ...
- 【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )
文章目录 一.动画的核心类 Animation 二.动画的核心类 CurvedAnimation 三.动画的核心类 AnimationController 四.动画的核心类 Tween 五.相关资源 ...
- 【Flutter】Animation 动画 ( Flutter 动画类型 | Flutter 动画的核心类 )
文章目录 一.Flutter 动画类型 二.Flutter 动画的核心类 三.相关资源 Flutter Animation 动画 : Flutter 动画类型 为 Widget 组件添加动画 为动画添 ...
- 转:Flutter动画一
1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才会觉得炫酷.移动端的动画库有非常的多,例如iOS上的Pop.web端的animate.css.Android端的An ...
- 学习笔记-Flutter 动画详解(一)
Flutter 动画详解(一) 本文主要介绍了动画的原理相关概念,对其他平台的动画做了一个简要的梳理,并简要的介绍了Flutter动画的一些知识. 1. 动画介绍 动画对于App来说,非常的重要.很多 ...
- flutter 动画展开菜单_Flutter 动画详解(一)
本文主要介绍了动画的原理相关概念,对其他平台的动画做了一个简要的梳理,并简要的介绍了Flutter动画的一些知识. 1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才 ...
- 史上最详细Flutter 动画讲解
1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才会觉得炫酷.移动端的动画库有非常的多,例如iOS上的Pop.web端的animate.css.Android端的An ...
- flutter 点击旋转动画_让动画实现更简单,Flutter 动画简易教程!
Flutter中的动画功能强大且易于使用.接下来通过一个具体的实例,您将学到关于 Flutter 动画的一切. 难度:中级 今天,我们无法想象移动应用程序里面没有任何动画,当您从一页跳转到另一页时,或 ...
- Android源码解析(一)动画篇-- Animator属性动画系统
Android源码解析-动画篇 Android源码解析(一)动画篇-- Animator属性动画系统 Android源码解析(二)动画篇-- ObjectAnimator Android在3.0版本中 ...
最新文章
- 深入浅出统计学(十一)总体和样本的估计
- 一个项目从开工到交付使用需要经历的过程
- 黑马2016java_2016年成功的Java开发人员简介
- 笔记本(华硕UL80VT)软件超频setFSB
- php coder 乱码,MySQL 乱码 与 字符集
- 将windows c盘安装在linux,将WindowsC盘hda1安装在Linux文件系统的/winsys目录下,命令是()。...
- Python成长之路第一篇(1)__字符串初识
- 我的世界服务器起床地图维修,Minecraft·起床战争地图更新来了!地图“雪仗”全面解读!...
- cad卸载_CAD卸载不干净,如何清理CAD注册表
- 详细介绍ADMM交替方向乘子法
- Python编程从入门到实践(第2版)个人学习笔记
- 春招面试阿里,面试官让我说说Java8的新特性
- GitHub上最火的两份Java面试小册,Star已经超百万
- 代码生成器的使用步骤
- 两步实现在网站左下角实现音乐播放器弹窗听歌
- 锐雅中国集团公司怎么样?
- RecyclerView的使用(二)——拖曳移动和滑动删除
- Karma与TSLint
- 在Excel中批量下载网络图片,存放到右方单元格或插入到批注,#excel插件
- 医疗物联网平台架构图
热门文章
- Could not transfer artifact (https://repo.maven.apache.org/maven2): Received fatal alert: protocol_v
- 有多远滚多远 html5游戏,68微信游戏有多远滚多远怎样能得高分
- 计算机的优缺点英语作文100词,英语作文 电脑的优点和缺点_900字_英语作文
- 使用Plumber和React缩放R
- 计算机专业可以转行医学吗,医学,会计,
- 阶乘因式分解(二) nyist
- 火猴之ppt动画效果实现(firemonkey)
- warning: unused variable ‘D‘ [-Wunused-variable]|
- 微信公众号支付问题 - 当前页面的URL未注册
- 后台弹出页面或模式窗口