一、Flutter 的宣告式檢視開發
// Android 設定某文字控制元件展示文案為 Hello World TextView textView = (TextView) findViewById(R.id.txt); textView.setText("Hello"); // iOS 設定某文字控制元件展示文案為 Hello World UILabel *label = (UILabel *)[self.view viewWithTag:100]; label.text = @"Hello";
對我們來說,如果要實現同樣的需求,則要稍微麻煩點:
除了設計好 Widget 佈局方案之 外,還需要提前維護一套文案資料集,
併為需要變化的 Widget 繫結資料集中的資料,使 Widget 根據這個資料集完成渲染。
總結來說,指令式程式設計強調精確控制過程細節;而宣告式程式設計強調通過意圖輸出結果整體。
對應到 Flutter 中,意圖是繫結了元件狀態的 State,結果則是重新渲染後的元件。
在 Widget 的生命週期內,應用到 State 中的任何更改都將強制 Widget 重新構建。
其中,對於元件完成建立後就無需變更的場景,狀態的繫結是可選項。
這裡“可選”就區分出了 Widget 的兩種型別,
即:StatelessWidget 不帶繫結狀態,而 StatefulWidget 帶綁 定狀態。
當你所要構建的使用者介面不隨任何狀態資訊的變化而變化時,需要選擇使用 StatelessWidget,反之則選用 StatefulWidget。
前者一般用於靜態內容的展示,而後 者則用於存在互動反饋的內容呈現中。
二、Widget 選型的基本原則
接下來,我分別和你介紹 StatelessWidget 和 StatefulWidget,總結一些關於 Widget 選型的基本原則。
StatelessWidget
在 Flutter 中,Widget 採用由父到子、自頂向下的方式進行構建,父 Widget 控制著子 Widget 的顯示樣式,其樣式配置由父 Widget 在構建時提供。
用這種方式構建出的 Widget,有些(比如 Text、Container、Row、Column 等)在建立 時,除了這些配置引數之外不依賴於任何其他資訊,
換句話說,它們一旦建立成功就不再關 心、也不響應任何資料變化進行重繪。
在 Flutter 中,這樣的 Widget 被稱為 StatelessWidget(無狀態元件)。
這裡有一張 StatelessWidget 的示意圖,如下所示:
可以看到,在構造後,build 方法隨即將子元件 RichText 通過其屬性列表(如文字 data、對齊方式 textAlign、文字展示方向 textDirection 等)初始化後返 回,之後 Text 內部不再響應外部資料的變化。
那麼,什麼場景下應該使用 StatelessWidget 呢?
一個簡單的判斷規則:父 Widget 是否能通過初始化引數完全控制其 UI 展示效果?
如果能,那麼我們就可以使用 StatelessWidget 來設計建構函式介面了。
StatefulWidget
與 StatelessWidget 相對應的,有一些 Widget(比如 Image、Checkbox)的展示,除了父 Widget 初始化時傳入的靜態配置之外,
還需要處理使用者的互動(比如,使用者點選按 鈕)或其內部資料的變化(比如,網路資料回包),並體現在 UI 上。
StatefulWidget 示意圖
之前瞭解到,Widget 是不可變的,發生變化時需要銷燬重建,所以談不上狀態。
其實,StatefulWidget 是以 State 類代理 Widget 構建的設計方式實現的。