简介
- Flutter动画核心类:Animation类,它可以判断当前动画的状态(开始,停止,移动,前进,反向),它是由AnimationController管理的,并通过Listeners和StatusListeners管理动画状态的所发生的变化,我们先对动画有了大体的了解,下面我们对其中提到的类进行逐一学习
- 这次主要学习flutter动画中的 平移,缩放,旋转,透明度,插值器,是为之后的自定义动画做准备嗷!
Animation
- Animation对象本身随手记屏幕是无感知的,,它仅仅直到当前动画的插值和状态,,Animation对象是一个在一段时间内,一次生成一个区间值的类,其输出值可以是线性的、非线性的,控制器可以控制Animation的动画方式:正向、反向、中间进行切换。
Animatable
- Animatable是控制动画类型的类,比如我们需要控制动画过程中颜色值的变化,那么Animatable就用来控制色值的变化
AnimationController
- 上面提到的动画控制器即AnimationController,它负责在给定的时间段内,以线性的方式生成默认区间为(0.0, 1.0)的数字,我们可以通过AnimationController来创建Animation对象
// vsync: 该参数接受的是TickerProvidr(宿主)类型的对象,作用是阻止在屏幕锁屏时执行动画以避免不必要的资源浪费
AnimationController _controller = AnimationController(vsync: this, duration: duration)
AnimationController 的常用操作说明
属性 |
说明 |
controller.forward() |
正向开始执行动画 |
controller.reverse() |
反向开始执行动画 |
controller.reset() |
重置动画到初始状态 |
controller.dispose() |
取消/停止动画 |
AnimationStatus 动画状态说明
属性 |
说明 |
AnimationStatus.forward |
执行controller.forward() 会回调此状态 |
AnimationStatus.reverse |
执行controller.reverse() 会回调此状态 |
AnimationStatus.dismissed |
动画从controller.reverse() 反向执行 结束时会回调此方法 |
AnimationStatus.completed |
动画从controller.forward() 正向执行 结束时会回调此方法 |
Tween补间动画
- 通常AnimationController的取值范围是(0.0,1.0), 但是有些时候我们呢可能会需要不同范围或者类型的值,就需要使用Tween来定义并生成相应的值,例如:
// 缩放取值变化范围(1.0, 0.8)
Animation _scaleAnimation = _scaleAnimation = Tween(begin: 1, end: 0.8).animate(_controller);
- 释义:
- Tween作用:定义从输入范围(左区间)到输出范围(右区间)的映射
- Tween继承自Animatable,例如上面的例子随着动画改变色值:
final Tween _colorTween = ColorTween(begin : Colors.transparent, end:Colors.black54);
示例实现平移补间动画
import 'package:flutter/material.dart';
class SlideTransitionAnimationWidget extends StatefulWidget {
@override
SlideTransitionAnimationWidgetState createState() => new SlideTransitionAnimationWidgetState();
}
class SlideTransitionAnimationWidgetState extends State
with SingleTickerProviderStateMixin {
final Duration _duration = const Duration(milliseconds: 300);
AnimationController _controller;
Animation _animation;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SlideTransition'),
),
body: Center(
child: SlideTransition(
position: _animation,
child: Container(
height: 100,
width: 100,
color: Colors.black,
),
),
),
);
}
@override
void initState() {
_controller = AnimationController(vsync: this, duration: _duration);
_animation = Tween(begin: Offset(-1, 0), end: Offset(0, 0))
.animate(_controller)
..addListener(() {
// AnimationController产生的数值取决于屏幕刷新情况,一秒60帧
// 数值生成之后,每个Animation对象都会通过Listener进行回调,下面实现动画监听
setState(() {
print(_animation.value);
});
})
..addStatusListener((status) {
// 实现动画循环
if (status == AnimationStatus.completed) {
// 正向结束时回调
_controller.reverse();
} else if (status == AnimationStatus.dismissed) {
// 反向执行 结束时会回调此方法
_controller.forward();
}
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
示例实现缩放动画
添加
// 声明处:
Animation _scaleAnimation;
// initState中
_scaleAnimation = Tween(begin: 1.0, end:
0.5).animate(_controller);
// build中修改
body: Center(
child: ScaleTransition(
scale: _scaleAnimation,
child: Container(
height: 100,
width: 100,
color: Colors.black,
),
),
),
- 实现方式都是相同的,大家可以再尝试旋转以及透明效果
Curve
- Curve类似于Android中的插值器,插值器如果不了解可以看一下这篇文章
- 通过Curve,可以将动画过程设置为线性或者非线性,初始化如下:
final Curanimation curve = CurveAnimation(parent:controller, curve:Curves/easeIn);
示例将弹跳的插值器和透明度结合
import 'package:flutter/material.dart';
class SlideTransitionAnimationWidget extends StatefulWidget {
@override
SlideTransitionAnimationWidgetState createState() => new SlideTransitionAnimationWidgetState();
}
class SlideTransitionAnimationWidgetState extends State
with SingleTickerProviderStateMixin {
final Duration _duration = const Duration(milliseconds: 3000);
AnimationController _controller;
Animation _slideAnimation;
Animation _scaleAnimation;
Animation _fadeAnimation;
Animation _rotationAnimation;
Animation _curveAnimation;
final _opacityTween = Tween(begin: 0.1 ,end: 1.0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SlideTransition'),
),
body: Center(
// 做相应动画可以直接修改此处,看下源码动画的参数是什么即可
child: Opacity(
// 计算差值,就相当于在自定义的插值器前面设置一个数值转换器
// 将透明度的设置和弹跳的插值器结合,evaluate作用是使得弹跳的进度即为透明度设置的进度
opacity : _opacityTween.evaluate(_curveAnimation),
child: Container(
height: 100,
width: 100,
color: Colors.black,
),
),
),
);
}
@override
void initState() {
_controller = AnimationController(vsync: this, duration: _duration);
_scaleAnimation = Tween(begin: 1.0, end: 0.5).animate(_controller);
_fadeAnimation = Tween(begin: 1.0, end: 0.0).animate(_controller);
_rotationAnimation = Tween(begin: 0.0, end: 60.0).animate(_controller);
_curveAnimation = CurvedAnimation(parent: _controller, curve: Curves.bounceIn);
_slideAnimation = Tween(begin: Offset(-1, 0), end: Offset(0, 0))
.animate(_controller)
..addListener(() {
// AnimationController产生的数值取决于屏幕刷新情况,一秒60帧
// 数值生成之后,每个Animation对象都会通过Listener进行回调,下面实现动画监听
setState(() {
print(_slideAnimation.value);
});
})
..addStatusListener((status) {
// 实现动画循环
if (status == AnimationStatus.completed) {
// 正向结束时回调
_controller.reverse();
} else if (status == AnimationStatus.dismissed) {
// 反向执行 结束时会回调此方法
_controller.forward();
}
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
Demo地址