宣告式 UI 介紹
這篇介紹描述了 Flutter 所使用的宣告式 UI 和許多其他 UI 框架所使用的命令式 UI 的概念性差異
為什麼是宣告式 UI?
從 Win32 到 Web 再到 Android 和 iOS,框架通常使用一種命令式的程式設計風格來完成 UI 程式設計。這可能是你最熟悉的風格——手動建構一個全功能的 UI 例項,比如一個 UIView 或其他類似的內容,在隨後 UI 發生變化時,使用方法或 Setter 修改它。
為了減輕開發人員的負擔,無需編寫如何在不同的 UI 狀態之間進行切換的程式碼, Flutter 相反,讓開發人員描述當前的 UI 狀態,並將轉換交給框架。
然而,這需要稍微改變下如何操作 UI 的思考方式。
如何在命令式框架中修改 UI
思考像下面這樣一個簡單的例子:
在命令式風格中,你通常需要使用選擇器 findViewById
或類似函式獲取到 ViewB 的例項 b
和所有權,並呼叫相關的修改的方法(並隱含的使其失效)。例如:
// Imperative style
b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)
由於 UI 真實的來源可能比例項 b
本身的存活週期更長,你可能還需要在 ViewB 的建構函式中複製此配置。
在宣告式風格中,檢視配置(如 Flutter 的 Widget )是不可變的,它只是輕量的「藍圖」。要改變 UI,widget 會在自身上觸發重建(在 Flutter 中最常見的方法是在 StatefulWidget
上呼叫 setState()
)並構造一個新的 Widget 子樹。
// Declarative style
return ViewB(
color: red,
child: const ViewC(),
);
在這裡,當用戶介面發生變化時,Flutter 不會修改舊的例項 b
,而是構造新的 widget 例項。框架使用 RenderObject
管理傳統 UI 物件的職責(比如維護佈局的狀態)。
RenderObject
在幀之間保持不變,
Flutter 的輕量級 widget 通知框架在狀態之間修改 RenderObject
,
Flutter 框架則處理其餘部分。