一. 计时器
要使用计时器先要导入dart:async包,
整个计时器体验和JS基本一致
1. Duration 间隔
这里先介绍一个dart自带的类: Duration
2. Timer 计时器
再介绍一个dart自带的非常好用的类Timer,
Timer(间隔, 回调)
import 'dart:async';
final timeout = Duration(seconds: 3);
Timer(timeout, () {
print("时间到,我被执行了!");
});
二. 动画
flutter动画分为两大类:
- 补间动画(
Tween
) - 基于物理的动画
在为widget添加动画之前,先让我们认识下动画的几个朋友:
-
Animation
:是Flutter动画库中的一个核心类,它生成指导动画的值; -
CurvedAnimation
:Animation
的一个子类,将过程抽象为一个非线性曲线; -
AnimationController
:Animation
的一个子类,用来管理Animation
; -
Tween
:在正在执行动画的对象所使用的数据范围之间生成值。例如,Tween
可生成从红到蓝之间的色值,或者从0到255;
1. Animation //动画过程
在Flutter中,Animation
对象本身和UI渲染没有任何关系。Animation
是一个抽象类,它拥有其当前值和状态(完成或停止)。
-
Animation
还可以生成除double之外的其他类型值,如:Animation
或() Animation
;() -
Animation
对象有状态。可以通过访问其value属性获取动画的当前值; -
Animation
对象本身和UI渲染没有任何关系;
2. CurvedAnimation //非线性动画曲线
里面传入一个控制器和一个曲线类型
final CurvedAnimation curve =
new CurvedAnimation(parent: controller, curve: Curves.easeIn);
3. AnimationController //动画控制器
AnimationController
是一个特殊的Animation
对象,在屏幕刷新的每一帧,就会生成一个新的值。默认情况下,AnimationController
在给定的时间段内会线性的生成从0.0到1.0的数字。 例如,下面代码创建一个Animation
对象:
final AnimationController controller = new AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
AnimationController
派生自Animation
,因此可以在需要Animation对象的任何地方使用。 但是,AnimationController
具有控制动画的其他方法:
-
forward()
:启动动画; -
reverse({double from})
:倒放动画; -
reset()
:重置动画,将其设置到动画的开始位置; -
stop({ bool canceled = true })
:停止动画;
当创建一个AnimationController
时,需要传递一个vsync
参数,存在vsync
时会防止屏幕外动画消耗不必要的资源,可以将stateful
对象作为vsync
的值。
4. Tween
默认情况下,AnimationController
对象的范围从0.0到1.0。
如果您需要不同的范围或不同的数据类型,则可以使用Tween来配置动画以生成不同的范围或数据类型的值。例如,以下示例,Tween
生成从-200.0到0.0的值:
final Tween doubleTween = new Tween(begin: -200.0, end: 0.0);
Tween
是一个无状态(stateless)对象,需要begin
和end
值。Tween
的唯一职责就是定义从输入范围到输出范围的映射。输入范围通常为0.0到1.0,但这不是必须的。
Tween
继承自Animatable
,而不是继承自Animation
。Animatable
与Animation
相似,不是必须输出double
值。例如,ColorTween
指定两种颜色之间的过渡。
final Tween colorTween =
new ColorTween(begin: Colors.transparent, end: Colors.black54);
Tween
对象不存储任何状态。相反,它提供了evaluate(Animation
方法将映射函数应用于动画当前值。 Animation
对象的当前值可以通过value()
方法取到。evaluate
函数还执行一些其它处理,例如分别确保在动画值为0.0和1.0时返回开始和结束状态。
说了这么多,到底该怎么用????
- 我们必须要混入
SingleTickerProviderStateMixin
类 - 我们要创建一个动画
- 要创建yi
- 我们可以为动画添加状态 或者 数值的监听(也可以不监听)
下面的例子是一个线性的动画的例子.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State
with SingleTickerProviderStateMixin {
//动画控制器需要传入 async, 要达到这一目的_MyHomePageState必须混合 SingleTickerProviderStateMixin
Animation animation; //创建了一个泛double型的Animation类对象
AnimationController controller; //创建了一个动画控制器 AnimationController类型
AnimationStatus animationState; //创建了一个动画状态 AnimationStatus类型
double animationValue; //一个double类型的数值, 用来展示动画的状态进度值
@override
void initState() {
super.initState();
controller = //初始化进程中为控制器做初始化.
AnimationController(duration: const Duration(seconds: 2), vsync: this);
animation = Tween(begin: 0, end: 300)
.animate(controller) //用一个Tween生成了一个Animation动画,同时给他了一个controller
..addListener(() {
//创建完动画后, 为其添加一个监听,
setState(() {
animationValue = animation.value;
//在这个监听里, 将这个动画的value赋值给之前创建的double数据animationValue
});
})
..addStatusListener((AnimationStatus state) {
//然后又为动画添加了一个状态监听
setState(() {
animationState = state; //把动画的状态赋值给我们之前创建的动画状态对象animationState
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("动画"),
),
body: Center(
child: Column(
children: [
RaisedButton(
child: Text('点击触发动画'),
onPressed: () {
controller.reset(); //点击时先复位动画
controller.forward(); //点击时先复位动画后播放
}),
Row(
children: [
Text('State:' + animationState.toString()), //用一个text展示一下状态
],
),
Row(
children: [
Text('Value:' + animationValue.toString()), //用一个text展示一下动画值
],
),
Container(
height: animation.value, //这容器的高和宽都是跟随动画变化的.
width: animation.value,
child: FlutterLogo(), //用这个图片来展示一下容器的变化
),
],
),
),
);
}
@override
void dispose() {
//当控件解散时把控制器销毁掉
controller.dispose();
super.dispose();
}
}
三. Android启动页
调用原生的安卓启动页并按照本地平台机制展示, 效果如下:
方法:
-
- 放一张图片在
...\android\app\src\main\res\drawable\splashimg.jpg
- 放一张图片在
-
- 在
android\app\src\main\res\drawable\launch_background.xml
中引用这张图片
- 在