Flutter学习笔记(36)--常用内置动画
如需转载,请注明出处:Flutter学习笔记(36)--常用内置动画
Flutter给我们提供了很多而且很好用的内置动画,这些动画仅仅需要简单的几行代码就可以实现一些不错的效果,Flutter的动画分为补间动画和基于物理的动画,基于物理的动画我们先不说。
补间动画很简单,Android里面也有补间动画,就是给UI设置初始的状态和结束状态,经过我们定义的一段时间,系统去帮助我们实现开始到结束的过渡变化,这就是补间动画。
今天我们要看的Flutter的内置动画就是补间动画,根据Flutter提供的动画组件,我们去设置初始、结尾的状态,并且定义一下这个变化过程所需要的时间,再经过系统的处理(其实就是setState())来达到动画的效果。
接下来我们会写一下常用的内置动画组件,并且提供一下动画效果的gif,方便大家更直观的去理解。
- AnimatedContainer
看到Container我们就会知道这是一个带有动画属性的容器组件,这个组件可以定义大小、颜色等属性,那么我们是不是就可以给这个组件设置初始和结束的大小及颜色的属性值,然后通过系统来帮助我们来补足中间过程的动画呢?
答案是可以的,下面看一下demo和动画效果:
class _MyHomePageState extends State<MyHomePage> {
double _width = 100.0;
double _height = 100.0;
Color _color = Colors.red;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: AnimatedContainer(
width: _width,
height: _height,
duration: Duration(seconds: ),
color: _color,
curve: Curves.bounceInOut,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_width = 300.0;
_height = 300.0;
_color = Colors.green;
});
},
tooltip: 'Increment',
child: Icon(Icons.adjust),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}

demo很简单,就是先定义好组件初始的大小和颜色,点击按钮,在按钮事件里面去更改大小和颜色的属性值。这里唯一需要特别说一下就是curve这个属性。
curve指的是动画曲线?我开始的时候不理解这个动画曲线是什么意思,后来看了一组图之后,豁然开朗。demo里面curve我们用的是Curves.bounceInOut。如下:

它其实就是一个非线性的动画的变化形式(变化过程)也可以理解为就是一种函数,也不知道这么说大家能不能理解。
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_bounce_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_decelerate.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_back.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_in_out_back.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_sine.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quad.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_cubic.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quart.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_quint.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_expo.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_circ.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_ease_out_back.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_in_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_elastic_out.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_fast_out_slow_in.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_slow_middle.mp4}
/// {@animation 464 192 https://flutter.github.io/assets-for-api-docs/assets/animation/curve_linear.mp4}
这里是每一种curve曲线的表现形式,大家可以看看,也可以在demo里面多尝试,或者可以看另一篇博客,有动画曲线Curves 效果。
AnimatedCrossFade
Flutter中文网:一个widget,在两个孩子之间交叉淡入,并同时调整他们的尺寸。
个人说明:CrossFade,故名思意,淡入淡出,AnimatedCrossFade组件包含两个子widget,一个firstChild一个secondChild,这两个组件根据状态(我们自己定义的一个标识)改变状态,
一个淡入,一个淡出,同时改变大小或颜色等属性。
class _MyHomePageState extends State<MyHomePage> {
bool _showFirst = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: AnimatedCrossFade(
firstChild: Container(
width: ,
height: ,
color: Colors.red,
alignment: Alignment.center,
child: Text('firstChild'),
),
secondChild: Container(
width: ,
height: ,
color: Colors.green,
alignment: Alignment.center,
child: Text('secondChild'),
),
duration: Duration(seconds: ),
crossFadeState:
_showFirst ? CrossFadeState.showFirst : CrossFadeState.showSecond,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_showFirst = false;
});
},
tooltip: 'Increment',
child: Icon(Icons.adjust),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}

Hero
Hero常用于页面跳转的过长动画,比如电商App有一个商品列表,列表的每个item都有一张缩略图,点击会跳转到详情页面,在Flutter中将图片从一个路由飞到另一个路由称为hero动画,尽管相同的动作有时也称为 共享元素转换。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Hero(
tag: 'heroTag',
child: ClipOval(
child: Image.asset(
'images/banner.png',
width: ,
height: ,
fit: BoxFit.cover,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return new HeroPage();
}));
});
},
tooltip: 'Increment',
child: Icon(Icons.adjust),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
详情页面:
import 'package:flutter/material.dart';
class HeroPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'HeroPage',
home: Scaffold(
appBar: AppBar(
title: Text('HeroPage'),
),
body: Center(
child: GestureDetector(
child: Hero(
tag: 'heroTag',
child: ClipOval(
child: Image.asset(
'images/banner.png',
width: ,
height: ,
fit: BoxFit.cover,
),
),
),
onTap: () {
Navigator.pop(context);
},
),
),
),
);
}
}
注:特别强调一下,为了将两个页面的元素关联起来,hero有个tag标识,前后两个页面的tag标识必须一样,不然的话元素是关联不起来的,也就意味着不会产生hero动画。
1.同级tag不允许相同。
2.前后页面想要有hero动画,tag必须相同。
3.前后关联起来的hero组件,其各自内部的child组件不是必须一样的,就是说前面的hero的子组件可以是image,后面的hero的子组件可以是image以外的其他组件。

AnimatedBuilder
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
AnimationController _animationController; @override
void initState() {
_animationController =
AnimationController(duration: Duration(seconds: ), vsync: this);
_animation =
new Tween(begin: 0.0, end: 200.0).animate(_animationController);
_animationController.forward();
super.initState();
} @override
void dispose() {
_animationController.dispose();
super.dispose();
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: AnimatedBuilder(
animation: _animation,
builder: (BuildContext context, Widget child) {
return Center(
child: Container(
color: Colors.red,
width: _animation.value,
height: _animation.value,
child: child,
),
);
},
));
}
}
AnimationController:动画控制器(定义动画过程时长)。
Animation:动画变化区间值(也可以说是开始和结束的关键帧值),demo里定义的值为初始0,结束200。
_animation.value:关键帧值是0和200,_animation.value的值为0--200之间连续变化的值(0-1-2-3-...-198-199-200)。

DecoratedBoxTransition
Decortated可以给容器添加各种外观装饰,比如增加圆角、阴影等装饰。DecoratedBox的动画版本,可以给它的Decoration不同属性使用动画
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
Animation<Decoration> _animation;
AnimationController _animationController; @override
void initState() {
_animationController =
AnimationController(duration: Duration(seconds: ), vsync: this);
_animation = DecorationTween(
begin: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(0.0)),
color: Colors.red),
end: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30.0)),
color: Colors.green))
.animate(_animationController);
_animationController.forward();
super.initState();
} @override
void dispose() {
_animationController.dispose();
super.dispose();
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: DecoratedBoxTransition(
decoration: _animation,
child: Container(
width: ,
height: ,
),
),
),
);
}
}

FadeTransition
透明度变化动画,因为透明度也是在0-1之间变化的,所以animation就还继续用double类型的就可以了。
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
AnimationController _animationController; @override
void initState() {
_animationController =
AnimationController(duration: Duration(seconds: ), vsync: this);
_animation = Tween(begin: 1.0, end: 0.0).animate(_animationController);
_animationController.forward();
super.initState();
} @override
void dispose() {
_animationController.dispose();
super.dispose();
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: FadeTransition(
opacity: _animation,
child: Container(
width: ,
height: ,
decoration: BoxDecoration(
color: Colors.red,
),
),
),
),
);
}
}

- RotationTransition
旋转动画,对widget使用旋转动画 1~360°(Tween(begin: 0.0, end: 1.0))这里的0-1指的是0°-360°
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
AnimationController _animationController; @override
void initState() {
_animationController =
AnimationController(duration: Duration(seconds: ), vsync: this);
_animation = Tween(begin: 0.0, end: 1.0).animate(_animationController);
_animationController.forward();
super.initState();
} @override
void dispose() {
_animationController.dispose();
super.dispose();
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: RotationTransition(
turns: _animation,
child: Container(
width: ,
height: ,
decoration: BoxDecoration(
color: Colors.red,
),
child: Center(child: Text('data')),
),
),
),
);
}
}

ScaleTransition
缩放动画,Tween(begin: 1.0, end: 0.2)指的是原大小的倍数,demo里是由原大小缩小到原来的0.2倍。
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
AnimationController _animationController; @override
void initState() {
_animationController =
AnimationController(duration: Duration(seconds: ), vsync: this);
_animation = Tween(begin: 1.0, end: 0.2).animate(_animationController);
_animationController.forward();
super.initState();
} @override
void dispose() {
_animationController.dispose();
super.dispose();
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: ScaleTransition(
scale: _animation,
child: Container(
width: ,
height: ,
decoration: BoxDecoration(
color: Colors.red,
),
child: Center(child: Text('data')),
),
),
),
);
}
}

SizeTransition
仅一个方向进行缩放
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
AnimationController _animationController; @override
void initState() {
_animationController =
AnimationController(duration: Duration(seconds: ), vsync: this);
_animation = Tween(begin: 1.0, end: 0.2).animate(_animationController);
_animationController.forward();
super.initState();
} @override
void dispose() {
_animationController.dispose();
super.dispose();
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: SizeTransition(
axis: Axis.horizontal,
sizeFactor: _animation,
child: Center(
child: Container(
width: ,
height: ,
decoration: BoxDecoration(
color: Colors.red,
),
child: Center(child: Text('data')),
),
),
),
),
);
}
}

以上!有任何疑问欢迎留言!
Flutter学习笔记(36)--常用内置动画的更多相关文章
- MySQL学习笔记_7_MySQL常用内置函数
MySQL常用内置函数 说明: 1)可以用在SELECT/UPDATE/DELETE中,及where,orderby,having中 2)在函数里将字段名作为参数,变量的值就是字段所对应的每一行的值. ...
- hive学习笔记之七:内置函数
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- JavaWeb学习笔记--2.3内置对象
参考资料:http://www.cnblogs.com/qqnnhhbb/archive/2007/10/16/926234.html 目录 1. JSP内置对象分类2. 属性保存范围 2.1 pag ...
- springboot学习笔记:6.内置tomcat启动和外部tomcat部署总结
springboot的web项目的启动主要分为: 一.使用内置tomcat启动 启动方式: 1.IDEA中main函数启动 2.mvn springboot-run 命令 3.java -jar XX ...
- Oracle学习笔记十四 内置程序包
扩展数据库的功能 为 PL/SQL 提供对 SQL 功能的访问 用户 SYS 拥有所有程序包 是公有同义词 可以由任何用户访问 一些内置程序包 程序包名称 说明 STANDARD和DBMS_STAND ...
- Prometheus监控学习笔记之PromQL 内置函数
概述 Prometheus 提供了其它大量的内置函数,可以对时序数据进行丰富的处理.某些函数有默认的参数,例如:year(v=vector(time()) instant-vector).其中参数 v ...
- javascript学习笔记 - 引用类型 单体内置对象
七 单体内置对象 1.Global对象 不属于任何对象的属性和方法,都归于它.全局作用域中定义的变量.函数,都属于Global对象 1.1 URI编码 encodeURI <=>deco ...
- python学习三十八天常用内置函数分类汇总
python给我们提供丰富的内置函数,不用去写函数体,直接调用就可以运行,很方便快速给我提供开发所需要的函数. 1,查内存地址 id() 变量的内存地址 id() 2,输入输出 input() pr ...
- flutter常用内置动画组件
文章目录 AnimatedContainer AnimatedCrossFade Hero AnimatedBuilder DecoratedBoxTransition FadeTransition ...
随机推荐
- linux 多线程 信号
一个老系统的问题,用的system v消息队列同步等响应,通过alarm信号来进行超时控制.现在系统进行升级改造(所谓云化),原来进程处理的逻辑全部改成了线程框架,问题就出现了.alarm信号发出的时 ...
- Oracle 利用PLSQL一分钟将表结构(PROJ),从A库移植到B库,一分钟将A库中表数据移植到B库中!!!
导读(苦恼) 做多个项目的时候,可能会有这样的需求,需要把A项目中的某些功能移植到B项目上:移植途中,牵扯到顺便把表也要一块移植过去,若表字段较少,那还好,可能耗费10分钟就搞完了,万一碰上几十个字段 ...
- [计划任务 - dos]制作任务工具
语法 schtasks /create /tn TaskName /tr TaskRun /sc schedule [/mo modifier] [/d day] [/m month[,month.. ...
- STM32串口DMA接收数据错位——暴力解决方法
背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...
- vc程序设计--图形绘制1
利用绘图函数创建填充区.Windows通过使用当前画笔画一个图形的边界,然后用当前的刷子填充这个图形来创建-一个填充图形.共有三个填充图形,第一个是用深灰色画刷填充带圆角的矩形,第二个是采用亮 ...
- Rocket - util - Misc
https://mp.weixin.qq.com/s/kf4FvAFye_bRdT49Yow7Hg 简单介绍Misc中各个辅助方法的用途和实现. 1. ParameterizedBu ...
- 【Hadoop】hdfs,剖析文件上传
文件上传原理图 剖析文件写入 1.客户端(client)通过对DistributedFileSystem对象调用create()来新建文件: FSDataOutputStream outputStre ...
- Java实现 LeetCode 472 连接词
472. 连接词 给定一个不含重复单词的列表,编写一个程序,返回给定单词列表中所有的连接词. 连接词的定义为:一个字符串完全是由至少两个给定数组中的单词组成的. 示例: 输入: ["cat& ...
- Java实现 LeetCode 319 灯泡开关
319. 灯泡开关 初始时有 n 个灯泡关闭. 第 1 轮,你打开所有的灯泡. 第 2 轮,每两个灯泡你关闭一次. 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭).第 i 轮,每 ...
- Java实现 LeetCode 149 直线上最多的点数
149. 直线上最多的点数 给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上. 示例 1: 输入: [[1,1],[2,2],[3,3]] 输出: 3 解释: ^ | | o | ...