跳至主要內容

宣告式 UI 簡介

本簡介描述了 Flutter 所使用的宣告式風格與許多其他 UI 框架所使用的命令式風格之間的觀念差異。

為什麼要使用宣告式 UI?

#

從 Win32 到網頁到 Android 和 iOS 的框架通常使用命令式的 UI 程式設計風格。這可能是您最熟悉的風格——您手動建構一個完整功能的 UI 實體,例如 UIView 或等效物,然後在 UI 變更時使用方法和 setter 來修改它。

為了減輕開發人員必須編寫如何在各種 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`,並在其上調用修改(並隱式地使其失效)。例如

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

您可能還需要在 ViewB 的建構函式中複製此配置,因為 UI 的事實來源可能比實例 `b` 本身更長壽。

在宣告式風格中,視圖配置(例如 Flutter 的 Widgets)是不可變的,並且只是輕量級的「藍圖」。為了更改 UI,Widget 會觸發自身的重建(在 Flutter 中最常見的是在 StatefulWidget 上調用 `setState()`),並建構新的 Widget 子樹。

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

在這裡,當 UI 變更時,Flutter 不是修改舊的實例 `b`,而是建構新的 Widget 實例。框架使用 RenderObjects 在幕後管理傳統 UI 物件的許多職責(例如維護佈局的狀態)。RenderObjects 在幀之間持續存在,而 Flutter 的輕量級 Widgets 會告知框架在狀態之間修改 RenderObjects。Flutter 框架會處理其餘的事情。