手把手教你用Flutter做炫酷动画
導讀:隨著技術的發展,很多網頁開發技術都帶有動畫效果,比如淡入淡出、漸變、變大變小,等等。Flutter中的動畫效果可以用酷炫來形容,這也是Flutter的一大特色。現代的應用程序不僅僅需要程序穩定、好用,還需要好看,體驗好。那么動畫效果是必不可少的。
作者:亢少軍
來源:大數據DT(ID:bigdatadt)
?
01 動畫概念
動畫顧名思義,就是動起來的畫面。如果一直持續的動再加上音頻那就是我們平時看的電影了。那么畫面為什么會動起來了呢?在回答這個問題之前,我們先引入一個概念。
人眼在觀察景物時,光信號傳入大腦神經,需經過一段短暫的時間,光的作用結束后,視覺形象并不立即消失,這種殘留的視覺稱“后像”,視覺的這一現象則被稱為“視覺暫留”。
視覺暫留被認為是電影的最重要的一個理論基礎。我們看到的動畫,實際上是一連串的畫面組成,只不過是以很快的速度去播放,人眼在下一個畫面出來之前,還殘留著上一個畫面的視覺,看起來就像是在沒有間隔的播放這一系列的圖片,也就是我們稱之為的動畫。
1. 幀與FPS
幀就是影像動畫中最小單位的單幅影像畫面,一幀就是一副靜止的畫面。比如我們看到的電影膠片中的每一格即為一幀,電影通常為24幀。
幀又分為關鍵幀和過渡幀,如下所示:
-
關鍵幀:相當于二維動畫中的原畫,指角色或者物體運動或變化中的關鍵動作所處的那一幀。
-
過渡幀:關鍵幀與關鍵幀之間的動畫可以由軟件來創建,叫做過渡幀或者中間幀。
FPS(Frame Per Second),即每秒顯示幀的數量。電影每秒播放24幀,即幀率為24FPS。幀率越大則顯示的畫面越流暢,動畫及視頻是同一個原理。
2. 插值器/估值器
為了使得動畫呈現出豐富的動畫效果,就需要使用非線性動畫,插值器與估值器可以解決這個問題。概念如下所示:
-
插值器:設置屬性值從初始值過渡到結束值的變化規律,如勻速、加速及減速等等。即確定了動畫效果變化的模式,如勻速變化、加速變化等等。主要應用于實現非線性運動的動畫效果。
-
估值器:設置屬性值從初始值過渡到結束值的變化具體數值。估值器的作用是協助插值器實現非線性運動的動畫效果。
插值器決定值的變化規律(勻速、加速),即決定的是變化趨勢,而接下來的具體變化數值則交給估值器。
如:動畫進行了50%(初始值=100,結束值=200 ),那么勻速插值器計算出了當前屬性值改變的百分比是50%,那么估值器則負責計算當前屬性值 = 100 + (200-100)x50% = 150。
插值器其實并不復雜,就是一個數學函數,設置屬性值從初始值過渡到結束值的變化規律。每個平臺都有自己定義好的一系列插值器,可以供開發者選擇使用,也提供自定義的接口,本質上是一個貝塞爾函數。
3. Flutter中的動畫類型
Flutter中動畫分為兩類,如下所示:
-
補間(Tween)動畫:定義開始點、結束點、時間和速度等參數,然后由框架自動計算如何從開始點過度達到結束點。
-
基于物理的動畫:模擬真實世界的行為。例如,當你擲球時,球在何處落地,取決于拋球速度有多快、球有多重、距離地面有多遠。
?
02 Flutter的動畫相關類
首先來看下Flutter的動畫基礎概念和相關類,如下所示:
-
Animation:Flutter中動畫的核心類
-
AnimationController:動畫管理類
-
CurvedAnimation:用于定義非線性曲線動畫
-
Tween:補間對象,用于計算動畫使用的數據范圍之間的插值。
-
Listeners和StatusListeners:用于監聽動畫狀態改變
1. Animation介紹
Flutter中的動畫核心類,我們可以理解為Animation是Flutter中動畫的基類。它是個抽象類(abstract),所以不能夠直接創建其對象來使用動畫。Animation具有以下特性:
-
Animation對象知道動畫的當前狀態(例如,它是開始、停止還是向前或向后移動),但它不知道屏幕上顯示的內容。
-
Flutter中的Animation對象是一個在一段時間內依次生成一個區間之間值的類。Animation對象的輸出可以是線性的、曲線的、一個步進函數或者任何其他可以設計的映射。根據Animation對象的控制方式,動畫可以反向運行,甚至可以在中間切換方向。
-
Animation還可以生成除double之外的其他類型值,如:Animation<Color> 或 Animation<Size>。
-
Animation對象有狀態,可以通過訪問其value屬性獲取動畫的當前值。
-
Animation對象本身和UI渲染沒有任何關系。
??
2. AnimationController動畫管理類
AnimationController是一個特殊的Animation對象。其繼承自Animation ,因此可以在需要Animation對象的任何地方使用它。默認情況下,AnimationController在給定的持續時間內線性生成從0.0到1.0的值。AnimationController在不使用的時候需要dispose,否則會造成資源的泄漏。AnimationController對象創建如下所示:
?AnimationController?controller?=?AnimationController(duration:?const?Duration(milliseconds:?2000),vsync:?this);上述是AnimationController 對象的創建方式,構造函數第一個參數是動畫執行的時間,單位是毫秒。第二個vsync傳入是防止動畫離屏之后繼續消耗資源。
vsync對象會綁定動畫的定時器到一個可視的Widget,所以當Widget不顯示時,動畫定時器將會暫停,當Widget再次顯示時,動畫定時器重新恢復執行,這樣就可以避免動畫相關UI不在當前屏幕時消耗資源。如果要使用自定義的State對象作為vsync時,請包含TickerProviderStateMixin,代碼結構大致如下所示:
class?MyApp?extends?StatefulWidget?{_AnimationApp?createState()?=>?_AnimationApp(); }class?_AnimationApp?extends?State<MyApp>?with?SingleTickerProviderStateMixin?{//動畫實現 }這里需要提一下TickerProvider類,它的主要作用是獲取每一幀刷新的通知,作用相當于給動畫添加了一個動起來的引擎。
AnimationController 提供了幾個常用的方法。
<!--開始動畫,從開始值向結束值--> TickerFuture?forward({?double?from?})?{}<!--開始反向運行此動畫--> TickerFuture?reverse({?double?from?})?{}<!--開始執行動畫,結束后重新啟動--> TickerFuture?repeat({?double?min,?double?max,?Duration?period?})?{}<!--使用阻尼效果驅動動畫--> TickerFuture?fling({?double?velocity:?1.0?})?{}<!--停止動畫--> void?stop({?bool?canceled:?true?})?{}<!--釋放此對象使用的資源,此方法調用后不再控制器對象不再可用--> void?dispose()?{}3. CurvedAnimation非線性動畫
CurvedAnimation繼承Animation,它將動畫過程定義為一個非線性曲線,屬于Animation<double>類型。構建其對象的方式如下所示:
CurvedAnimation?curve?=?CurvedAnimation(parent:?controller,?curve:?Curves.easeIn);構造函數中傳入控制器和要執行的曲線方式。Curves類定義了許多常用的曲線,也可以創建自己的,例如我們使用數學函數Math.sin方法構建一個抖動的曲線,代碼如下所示:
class?ShakeCurve?extends?Curve?{@overridedouble?transform(double?t)?{return?math.sin(t?*?math.PI?*?2);} }Flutter定義了一系列的插值器,封裝在Curves類中,有下面13種效果:
-
linear
-
decelerate
-
ease
-
easeIn
-
easeOut
-
easeInOut
-
fastOutSlowIn
-
bounceIn
-
bounceOut
-
bounceInOut
-
elasticIn
-
elasticOut
-
elasticInOut
4. Tween補間值生成類
AnimationController對象的范圍為0.0到1.0。如果需要不同的范圍或不同的數據類型,可以使用Tween將動畫配置為插入到不同的范圍或數據類型。例如,以下Tween從0.0變為500.0:
Tween?doubleTween?=?Tween<double>(begin:?0.0,?end:?500.0);構造函數傳入只需要傳入begin和end兩個值,當然這里不一定只是double值。
Tween繼承自Animatable<T>,而不是繼承自Animation<T>。Animatable與Animation相似,不是必須輸出double值。例如,ColorTween指定兩種顏色之間的過渡。
final?Tween?colorTween?= ColorTween(begin:?Colors.transparent,?end:?Colors.black54);要使用Tween對象,請調用其animate()方法,傳入一個控制器對象。例如,以下代碼在100毫秒內生成從0到200的整數值。
final?AnimationController?controller?=?AnimationController(duration:?const?Duration(milliseconds:?100),?vsync:?this); Animation<int>?alpha?=?IntTween(begin:?0,?end:?200).animate(controller);注意:animate()返回的是一個Animation,而不是一個Animatable。
Flutter通過抽象類Animatable來實現估值器。Animatable可以根據不同的輸入,產出不同的數值。通過重載下面的函數來產生不同的估值器。
T?transform(double?t);它的最主要的子類是Tween,一個線性的估值器,實現如下,非常的簡單,就是一個線性函數。
T?lerp(double?t)?{assert(begin?!=?null);assert(end?!=?null);//返回值?=?開始值?+?(結束值?-?開始值)?*?傳入值return?begin?+?(end?-?begin)?*?t; }@override T?transform(double?t)?{//開始if?(t?==?0.0)return?begin;//結束if?(t?==?1.0)return?end;//中間值??return?lerp(t); }在Tween的基礎上實現了不同類型的估值器,如下所示:
-
ReverseTween
-
ColorTween
-
SizeTween
-
RectTween
-
IntTween
-
StepTween
-
ConstantTween
?
?
5. Listeners和StatusListeners動畫監聽
Animation對象可以有Listeners和StatusListeners,用addListener來進行動畫監聽和addStatusListener進行動畫狀態添加監聽。只要動畫的值發生變化,就會調用監聽器。我們通常可用調用setState以將動畫重置狀態。動畫開始,結束,前進或后退時調用StatusListener,下列是Flutter提供動畫的監聽方法。
<!--動畫添加監聽--> void?addListener(VoidCallback?listener);<!--動畫移除監聽--> void?removeListener(VoidCallback?listener);<!--動畫狀態添加監聽--> void?addStatusListener(AnimationStatusListener?listener);<!--動畫狀態移除監聽-->?? void?removeStatusListener(AnimationStatusListener?listener);動畫狀態如下:
<!--動畫狀態--> enum?AnimationStatus?{<!--動畫在開始時停止-->???dismissed,<!--動畫從開始狀態執行到結束狀態-->forward,<!--動畫反向執行,從結束狀態執行到開始狀態-->reverse,<!--動畫執行完成-->completed,}?
6. 動畫控制流程
當我們理解了插值器(Curve)、估值器(Tween)以及Ticker回調的原理。我們就可以理出AnimationController大致的工作流程。
隨著時間的流逝,插值器根據時間產生的值作為輸入,提供給估值器,產生動畫的實際效果值,結合Ticker的回調,渲染出當前動畫值的圖像。這也是補間動畫的工作原理。如下圖所示。
▲動畫控制流程圖
關于作者:亢少軍,資深開發者,創業者。專注于視頻通訊技術領域。國內首本Flutter著作《Flutter技術入門與實戰》作者。多年從事視頻會議、遠程教育等技術研發,對于Android、iOS以及跨平臺開發技術有比較深入的研究和應用,作為主要程序員開發了多個應用項目,涉及醫療、交通、銀行等領域。
延伸閱讀《Flutter技術入門與實戰》第2版
點擊上圖了解及購買
轉載請聯系微信:DoctorData
推薦語:本書是多位人工智能技術專家和大數據技術專家多年工作經驗的結晶,從工具使用、技術原理、算法設計、案例實現等多個維度對深度學習進行了系統的講解。內容選擇上,廣泛涉獵、重點突出、注重實戰;內容安排上,實例切入、由淺入深、循序漸進;表達形式上,深度抽象、化繁為簡、用圖說話。
-
圖書同步配套視頻:
https://flutter.ke.qq.com
-
Flutter開源項目請關注:
https://github.com/kangshaojun
-
Flutter交流學習群:894109159
-
作者QQ:283796665
微信:kangshaojun888
「大數據」內容合伙人之「鑒書小分隊」上線啦!
最近,你都在讀什么書?有哪些心得體會想要跟大家分享?
數據叔最近搞了個大事——聯合優質圖書出版商機械工業出版社華章公司發起鑒書活動。
簡單說就是:你可以免費讀新書,你可以免費讀新書的同時,順手碼一篇讀書筆記就行。詳情請在大數據公眾號后臺對話框回復合伙人查看。
有話要說????
Q:?Flutter還有哪些炫酷應用?
歡迎留言與大家分享
猜你想看????
-
推給我的廣告都跟我最近看的內容有關系,怎么做到的?
-
很火的深度學習框架PyTorch怎么用?手把手帶你安裝配置
-
天貓雙11、12306怎樣扛住流量高峰“集中轟炸”?一文全揭秘!
-
87萬人已開通5G套餐!8本書,給你劇透未來科技
更多精彩????
在公眾號對話框輸入以下關鍵詞
查看更多優質內容!
PPT?|?報告?|?讀書?|?書單?|?干貨?
大數據?|?揭秘?|?Python?|?可視化
AI?|?人工智能?|?5G?|?中臺
機器學習?|?深度學習?|?神經網絡
合伙人?|?1024?|?段子?|?數學
據統計,99%的大咖都完成了這個神操作
????
覺得不錯,請把這篇文章分享給你的朋友
轉載 / 投稿請聯系:baiyu@hzbook.com
更多精彩,請在后臺點擊“歷史文章”查看
點擊閱讀原文,了解更多
總結
以上是生活随笔為你收集整理的手把手教你用Flutter做炫酷动画的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手把手教你使用Pandas读取结构化数据
- 下一篇: 程序员春节自救指南