動畫簡介
精心設計的動畫讓 UI 感覺更直觀,有助於打造精緻應用的流暢外觀和感覺,並改善使用者體驗。Flutter 的動畫支援使得實現各種動畫型別變得容易。許多小部件,特別是Material 小部件,都附帶了其設計規範中定義的標準運動效果,但也可以自定義這些效果。
選擇一種方法
#在 Flutter 中建立動畫時,可以採用不同的方法。哪種方法適合你?為了幫助你做出決定,請觀看影片《如何選擇適合你的 Flutter 動畫小部件?》(也作為一篇配套文章釋出。)
(要深入瞭解決策過程,請觀看 Flutter Europe 上釋出的影片《正確使用 Flutter 動畫》。)
如影片所示,以下決策樹可幫助您決定在實現 Flutter 動畫時採用哪種方法。

動畫深入解析
#要更深入地瞭解 Flutter 動畫的工作原理,請觀看動畫深入解析。(也作為配套文章釋出。)
隱式和顯式動畫
#預封裝的隱式動畫
#如果預封裝的隱式動畫(最容易實現的動畫)符合您的需求,請觀看隱式動畫基礎知識。(也作為配套文章釋出。)
自定義隱式動畫
#要建立自定義隱式動畫,請觀看使用 TweenAnimationBuilder 建立您自己的自定義隱式動畫。(也作為配套文章釋出。)
內建隱式動畫
#要建立顯式動畫(您控制動畫,而不是讓框架控制它),也許可以使用內建的顯式動畫類之一。欲瞭解更多資訊,請觀看使用內建顯式動畫製作您的第一個定向動畫。(也作為配套文章釋出。)
顯式動畫
#如果您需要從頭開始構建顯式動畫,請觀看使用 AnimatedBuilder 和 AnimatedWidget 建立自定義顯式動畫。(也作為配套文章釋出。)
在新標籤頁中觀看 YouTube 影片:“使用 AnimatedBuilder 和 AnimatedWidget 建立自定義顯式動畫”
動畫型別
#通常,動畫要麼是補間動畫,要麼是基於物理的動畫。以下部分解釋了這些術語的含義,併為您提供了可以瞭解更多資訊的資源。
補間動畫
#“補間”是“in-betweening”的縮寫。在補間動畫中,定義了起始點和結束點,以及時間線和定義過渡時序和速度的曲線。框架計算如何從起始點過渡到結束點。
請參閱動畫教程,其中示例使用了補間動畫。
另請參閱
Tween、CurveTween和TweenSequence的 API 文件。
基於物理的動畫
#在基於物理的動畫中,運動被模擬成類似於真實世界的行為。例如,當你丟擲一個球時,它在哪裡以及何時落地取決於拋球的速度以及它離地面的距離。同樣,一個系在彈簧上的球落地(並彈跳)的方式與一個系在繩子上的球落地的方式不同。
使用物理模擬來為元件新增動畫
Flutter 開發指南動畫部分的一個配方。另請參閱
AnimationController.animateWith和SpringSimulation的 API 文件。
常見動畫模式
#大多數 UX 或動效設計師發現,在設計 UI 時,某些動畫模式被重複使用。本節列出了一些常用的動畫模式,並告訴您在哪裡可以學到更多。
動畫列表或網格
#這種模式涉及對列表中或網格中元素的新增或刪除進行動畫處理。
AnimatedList示例
此演示來自 示例應用目錄,展示瞭如何動畫新增元素到列表或移除選定元素。當用戶使用加號 (+) 和減號 (-) 按鈕修改列表時,內部 Dart 列表會同步。
共享元素過渡
#在此模式中,使用者從頁面中選擇一個元素(通常是影像),然後 UI 將選定的元素動畫到包含更多詳細資訊的新頁面。在 Flutter 中,您可以使用 `Hero` 小部件輕鬆實現路由(頁面)之間的共享元素過渡。
英雄動畫 如何建立兩種風格的英雄動畫
- 英雄在改變位置和大小的同時從一個頁面飛向另一個頁面。
- 英雄的邊界在從一個頁面飛向另一個頁面時,從圓形變為方形。
交錯動畫
#動畫被分解成更小的動作,其中一些動作被延遲。這些較小的動畫可能是順序的,也可能部分或完全重疊。
基本動畫概念和類
#Flutter 中的動畫系統基於型別化的 Animation 物件。小部件可以直接在它們的 build 函式中透過讀取其當前值並監聽其狀態變化來整合這些動畫,或者它們可以使用這些動畫作為更精細動畫的基礎,然後將這些動畫傳遞給其他小部件。
Animation<double>
#在 Flutter 中,一個 Animation 物件對螢幕上顯示的內容一無所知。Animation 是一個抽象類,它瞭解其當前值和狀態(已完成或已取消)。最常用的動畫型別之一是 Animation<double>。
一個 Animation 物件在特定持續時間內按順序生成兩個值之間的插值數字。Animation 物件的輸出可以是線性的、曲線的、階梯函式或您可以建立的任何其他對映。根據 Animation 物件的控制方式,它可以反向執行,甚至在中間切換方向。
動畫也可以插值除了 double 之外的其他型別,例如 Animation<Color> 或 Animation<Size>。
一個 Animation 物件擁有狀態。它的當前值始終在 .value 成員中可用。
Animation 物件對渲染或 build() 函式一無所知。
CurvedAnimation
#CurvedAnimation 將動畫進度定義為非線性曲線。
animation = CurvedAnimation(parent: controller, curve: Curves.easeIn);CurvedAnimation 和 AnimationController(在接下來的章節中描述)都屬於 Animation<double> 型別,因此它們可以互換使用。CurvedAnimation 包裝它正在修改的物件——你不需要透過子類化 AnimationController 來實現曲線。
您可以將 Curves 與 CurvedAnimation 配合使用。Curves 類定義了許多常用的曲線,或者您可以建立自己的曲線。例如:
import 'dart:math';
class ShakeCurve extends Curve {
@override
double transform(double t) => sin(t * pi * 2);
}如果你想將動畫曲線應用於 Tween,請考慮使用 CurveTween。
AnimationController
#AnimationController 是一個特殊的 Animation 物件,每當硬體準備好新幀時,它就會生成一個新值。預設情況下,AnimationController 在給定持續時間內線性地生成從 0.0 到 1.0 的數字。例如,此程式碼建立一個 Animation 物件,但不會啟動它執行:
controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);AnimationController 派生自 Animation<double>,因此可以在需要 Animation 物件的地方使用它。但是,AnimationController 具有控制動畫的附加方法。例如,您可以使用 .forward() 方法啟動動畫。數字的生成與螢幕重新整理相關聯,因此通常每秒生成 60 個數字。生成每個數字後,每個 Animation 物件都會呼叫附加的 Listener 物件。要為每個子項建立自定義顯示列表,請參閱 RepaintBoundary。
建立 AnimationController 時,您會為其傳遞一個 vsync 引數。vsync 的存在可以防止螢幕外動畫消耗不必要的資源。您可以透過將 SingleTickerProviderStateMixin 新增到類定義中,將您的有狀態物件用作 vsync。您可以在 GitHub 上的 animate1 中看到一個示例。
Tween
#預設情況下,AnimationController 物件的範圍從 0.0 到 1.0。如果您需要不同的範圍或不同的資料型別,可以使用 Tween 來配置動畫以插值到不同的範圍或資料型別。例如,下面的 Tween 從 -200.0 到 0.0:
tween = Tween<double>(begin: -200, end: 0);Tween 是一個無狀態物件,只接受 begin 和 end。Tween 的唯一作用是定義從輸入範圍到輸出範圍的對映。輸入範圍通常是 0.0 到 1.0,但這並非強制要求。
一個 Tween 繼承自 Animatable<T>,而不是 Animation<T>。一個 Animatable,像 Animation 一樣,不一定輸出 double。例如,ColorTween 指定了兩種顏色之間的漸變。
colorTween = ColorTween(begin: Colors.transparent, end: Colors.black54);Tween 物件不儲存任何狀態。相反,它提供了 evaluate(Animation<double> animation) 方法,該方法使用 transform 函式將動畫的當前值(介於 0.0 和 1.0 之間)對映到實際的動畫值。
Animation 物件的當前值可以在 .value 方法中找到。evaluate 函式還執行一些內務管理,例如確保當動畫值分別為 0.0 和 1.0 時返回 begin 和 end。
Tween.animate
#要使用 Tween 物件,請在 Tween 上呼叫 animate(),並傳入控制器物件。例如,以下程式碼在 500 毫秒內生成從 0 到 255 的整數值。
AnimationController controller = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this,
);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(controller);以下示例展示了一個控制器、一條曲線和一個 Tween:
AnimationController controller = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this,
);
final Animation<double> curve = CurvedAnimation(
parent: controller,
curve: Curves.easeOut,
);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(curve);動畫通知
#一個 Animation 物件可以有 Listeners 和 StatusListeners,透過 addListener() 和 addStatusListener() 定義。當動畫的值改變時,就會呼叫 Listener。Listener 最常見的行為是呼叫 setState() 來觸發重建。當動畫開始、結束、向前或向後移動時,就會呼叫 StatusListener,這由 AnimationStatus 定義。
程式碼實驗室、教程和文章
#以下資源是學習 Flutter 動畫框架的良好起點。每個文件都展示瞭如何編寫動畫程式碼。
隱式動畫程式碼實驗室
透過分步說明和互動式示例,涵蓋如何使用隱式動畫。動畫教程
解釋了 Flutter 動畫包中的基本類(控制器、Animatable、曲線、監聽器、構建器),並指導您逐步完成使用動畫 API 不同方面的補間動畫。本教程展示瞭如何建立您自己的自定義顯式動畫。Flutter 從零到一,第一部分 和 第二部分
Medium 文章,展示瞭如何使用補間動畫建立動畫圖表。休閒遊戲工具包
一個包含遊戲模板的工具包,其中包含如何使用 Flutter 動畫的示例。
其他資源
#請透過以下連結瞭解更多 Flutter 動畫知識