宣告式 UI 簡介

本簡介說明 Flutter 使用的宣告式風格與許多其他 UI 架構使用的命令式風格之間的概念差異。

為什麼要使用宣告式 UI?

從 Win32 到網頁,再到 Android 和 iOS 的架構通常使用命令式 UI 程式設計風格。這可能是您最熟悉的風格,您會手動建構一個功能齊全的 UI 實體,例如 UIView 或等效實體,然後在 UI 變更時使用方法和設定值來變異它。

為了減輕開發人員在各種 UI 狀態之間轉換的程式設計負擔,Flutter 讓開發人員描述目前的 UI 狀態,並將轉換留給架構處理。

不過,這需要稍稍轉換一下思考方式,才能操作 UI。

如何在宣告式架構中變更 UI

請考慮以下簡化的範例

View B (contained by view A) morphs from containing two views, c1 and c2, to containing only view c3

在命令式風格中,您通常會前往 ViewB 的擁有者並使用選擇器或 findViewById 或類似函數來擷取實例 b,並呼叫其變異(並隱含地使其無效)。例如

// Imperative style
b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)

您可能還需要在 ViewB 的建構函式中複製此組態,因為 UI 的真實來源可能會比執行個體 b 本身更長久。

在宣告式樣式中,檢視組態(例如 Flutter 的小工具)是不可變的,而且僅是輕量級的「藍圖」。若要變更 UI,小工具會觸發自身重建(最常見的方式是在 Flutter 中對 StatefulWidgets 呼叫 setState()),並建構新的 Widget 子樹。

// Declarative style
return ViewB(
  color: red,
  child: const ViewC(),
);

在此,當 UI 變更時,Flutter 並非變異舊執行個體 b,而是建構新的 Widget 執行個體。此架構會在幕後使用 RenderObjects 管理傳統 UI 物件的許多責任(例如維護配置的狀態)。RenderObjects 會在畫面之間持續存在,而 Flutter 的輕量級 Widgets 會指示架構在狀態之間變異 RenderObjects。其餘部分則由 Flutter 架構處理。