Flutter Widget中的State

鴻鵠當高遠發表於2021-04-04

一、Flutter 的宣告式檢視開發

在原生系統(Android、iOS)或原生JavaScript 開發的話,應該知道檢視開發是命令式的,需要精確地告訴作業系統或瀏覽器用何種方式去做事情
比如,如果我們想要變更介面的某個文案,則需要找到具體的文字控制元件並呼叫它的控制元件方法命令,才能完成文字變更。
 
 // 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";

  

與此不同的是,Flutter 的檢視開發是宣告式的,其核心設計思想就是將檢視和資料分離, 這與 React 的設計思路完全一致。

 對我們來說,如果要實現同樣的需求,則要稍微麻煩點:

除了設計好 Widget 佈局方案之 外,還需要提前維護一套文案資料集,

併為需要變化的 Widget 繫結資料集中的資料,使 Widget 根據這個資料集完成渲染。

但是,當需要變更介面的文案時,我們只要改變資料集中的文案資料,並通知 Flutter 框架 觸發 Widget 的重新渲染即可。
這樣一來,開發者將無需再精確關注 UI 程式設計中的各個過程 細節,只要維護好資料集即可。
比起命令式的檢視開發方式需要挨個設定不同元件 (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 的示意圖,如下所示:

 

Flutter Widget中的State

 

StatelessWidget 示意圖

可以看到,在構造後,build 方法隨即將子元件 RichText 通過其屬性列表(如文字 data、對齊方式 textAlign、文字展示方向 textDirection 等)初始化後返 回,之後 Text 內部不再響應外部資料的變化。

那麼,什麼場景下應該使用 StatelessWidget 呢?

一個簡單的判斷規則:父 Widget 是否能通過初始化引數完全控制其 UI 展示效果?

如果能,那麼我們就可以使用 StatelessWidget 來設計建構函式介面了。

 

 StatefulWidget

與 StatelessWidget 相對應的,有一些 Widget(比如 Image、Checkbox)的展示,除了父 Widget 初始化時傳入的靜態配置之外,

還需要處理使用者的互動(比如,使用者點選按 鈕)或其內部資料的變化(比如,網路資料回包),並體現在 UI 上。

換句話說,這些 Widget 建立完成後,還需要關心和響應資料變化來進行重繪。在 Flutter 中,這一類 Widget 被稱為 StatefulWidget(有狀態元件)。
這裡有一張 StatefulWidget 的示意圖,如下所示:

 

Flutter Widget中的State

 

  StatefulWidget 示意圖

之前瞭解到,Widget 是不可變的,發生變化時需要銷燬重建,所以談不上狀態。

其實,StatefulWidget 是以 State 類代理 Widget 構建的設計方式實現的。

 

相關文章