簡介
- 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<double> _scaleAnimation = _scaleAnimation = Tween<double>(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<SlideTransitionAnimationWidget>
with SingleTickerProviderStateMixin {
final Duration _duration = const Duration(milliseconds: 300);
AnimationController _controller;
Animation<Offset> _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<Offset>(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<double> _scaleAnimation;
// initState中
_scaleAnimation = Tween<double>(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<SlideTransitionAnimationWidget>
with SingleTickerProviderStateMixin {
final Duration _duration = const Duration(milliseconds: 3000);
AnimationController _controller;
Animation<Offset> _slideAnimation;
Animation<double> _scaleAnimation;
Animation<double> _fadeAnimation;
Animation<double> _rotationAnimation;
Animation<double> _curveAnimation;
final _opacityTween = Tween<double>(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<double>(begin: 1.0, end: 0.5).animate(_controller);
_fadeAnimation = Tween<double>(begin: 1.0, end: 0.0).animate(_controller);
_rotationAnimation = Tween<double>(begin: 0.0, end: 60.0).animate(_controller);
_curveAnimation = CurvedAnimation(parent: _controller, curve: Curves.bounceIn);
_slideAnimation = Tween<Offset>(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();
}
}