Widget生命週期的理解
什麼是生命週期呢?
做過Android/iOS開發的都知道我們的頁面都是由生命週期,我們在不同生命週期的回撥方法裡會做一些處理。對於flutter而言 一切皆是Widget,所以瞭解Widget的生命週期也是必不可少的!
-
客戶端開發:iOS開發中我們需要知道UIViewController從建立到銷燬的整個過程,Android開發中我們需要知道Activity從建立到銷燬的整個過程。以便在不同的生命週期方法中完成不同的操作;
-
前端開發中:Vue、React開發中元件也都有自己的生命週期,在不同的生命週期中我們可以做不同的操作;
Flutter小部件的生命週期
一、StatelessWidget生命週期
- StatelessWidget可以由父Widget直接傳入值,呼叫build方法來構建,整個過程非常簡單;下圖是官網對StateLessWidget 生命週期的描述,不難看出StateLessWidget只有兩個過程,初始化和build。
StatelessWidget的生命週期 class JGHomeContent extends StatelessWidget { final String message; HYHomeContent(this.message) { print("建構函式被呼叫"); } @override Widget build(BuildContext context) { print("呼叫build方法"); return Text(message); } }
二、StatefulWidget生命週期
- 而StatefulWidget需要通過State來管理其資料,並且還要監控狀態的改變決定是否重新build整個Widget;
- StatefulWidget是有狀態的Widget,Widget創建出來之後是不可變,但是狀態是可以變的,管理這個狀態的就是State,我們可以通過呼叫期setState方法去重新整理Widget。
在下圖中,灰色部分的內容是Flutter內部操作的,我們並不需要手動去設定它們;
白色部分表示我們可以去監聽到或者可以手動呼叫的方法;
我們知道StatefulWidget本身由兩個類組成的:StatefulWidget
State
,我們分開進行分析
首先,執行StatefulWidget中相關的方法:
-
1、執行StatefulWidget的建構函式(Constructor)來創建出StatefulWidget;
-
2、執行StatefulWidget的createState方法,來建立一個維護StatefulWidget的State物件;
其次,呼叫createState建立State物件時,執行State類的相關方法:
-
1、執行State類的構造方法(Constructor)來建立State物件;
-
2、執行initState,我們通常會在這個方法中執行一些資料初始化的操作,或者也可能會發送網路請求;
-
注意:這個方法是重寫父類的方法,必須呼叫super,因為父類中會進行一些其他操作;
-
並且如果你閱讀原始碼,你會發現這裡有一個註解(annotation):@mustCallSuper
-
3、執行didChangeDependencies方法,這個方法在兩種情況下會呼叫
-
情況一:呼叫initState會呼叫;
-
情況二:從其他物件中依賴一些資料發生改變時,比如前面我們提到的InheritedWidget(這個後面會講到);
-
4、Flutter執行build方法,來看一下我們當前的Widget需要渲染哪些Widget;
-
5、當前的Widget不再使用時,會呼叫dispose進行銷燬;
-
6、手動呼叫setState方法,會根據最新的狀態(資料)來重新呼叫build方法,構建對應的Widgets;
-
7、執行didUpdateWidget方法是在當父Widget觸發重建(rebuild)時,系統會呼叫didUpdateWidget方法;
下圖是關於State
、StatefulElement
、Component
、Element
的關係圖,可以更好的理解StatefulWidget
的生命週期。
- initState 適合做初始化工作
- build 避免在build內做些邏輯程式碼,因為在呼叫setState是build方法會重新觸發,容易產生問題
- dispose 釋放資源。
// StatefulWidget的生命週期 class JGHomeContent extends StatefulWidget { JGHomeContent() { print("1.呼叫JGHomeContent的constructor方法"); } @override _JGHomeContentState createState() { print("2.呼叫JGHomeContent的createState方法"); return _JGHomeContentState(); } } class _JGHomeContentState extends State<JGHomeContent> { int _counter = 0; _JGHomeContentState() { print("3.呼叫_JGHomeContentState的constructor方法"); } @override void initState() { // 呼叫: 這裡是必須呼叫super final TextStyle style = TextStyle(); super.initState(); print("4.呼叫_JGHomeContentState的initState方法"); } @override void didUpdateWidget(JGHomeContent oldWidget) { super.didUpdateWidget(oldWidget); print("didUpdateWidget"); } @override void didChangeDependencies() { super.didChangeDependencies(); print("呼叫_JGHomeContentState的didChangeDependencies方法"); } @override Widget build(BuildContext context) { print("5.呼叫_JGHomeContentState的build方法"); return Column( children: <Widget>[ RaisedButton( child: Icon(Icons.add), onPressed: () { setState(() { _counter++; }); }, ), Text("數字:$_counter") ], ); } @override void dispose() { print("6.呼叫_JGHomeContentState的dispose方法"); super.dispose(); } }