State的生命周期
本文摘自:https://book.flutterchina.club/chapter3/flutter_widget_intro.html
initState:當(dāng)Widget第一次插入到Widget樹時會被調(diào)用,對于每一個State對象,F(xiàn)lutter framework只會調(diào)用一次該回調(diào),所以,通常在該回調(diào)中做一些一次性的操作,如狀態(tài)初始化、訂閱子樹的事件通知等。不能在該回調(diào)中調(diào)用BuildContext.inheritFromWidgetOfExactType(該方法用于在Widget樹上獲取離當(dāng)前widget最近的一個父級InheritFromWidget,關(guān)于InheritedWidget我們將在后面章節(jié)介紹),原因是在初始化完成后,Widget樹中的InheritFromWidget也可能會發(fā)生變化,所以正確的做法應(yīng)該在在build()方法或didChangeDependencies()中調(diào)用它。
didChangeDependencies():當(dāng)State對象的依賴發(fā)生變化時會被調(diào)用;例如:在之前build()?中包含了一個InheritedWidget,然后在之后的build()?中InheritedWidget發(fā)生了變化,那么此時InheritedWidget的子widget的didChangeDependencies()回調(diào)都會被調(diào)用。典型的場景是當(dāng)系統(tǒng)語言Locale或應(yīng)用主題改變時,F(xiàn)lutter framework會通知widget調(diào)用此回調(diào)。
build():此回調(diào)讀者現(xiàn)在應(yīng)該已經(jīng)相當(dāng)熟悉了,它主要是用于構(gòu)建Widget子樹的,會在如下場景被調(diào)用:
在調(diào)用initState()之后。
在調(diào)用didUpdateWidget()之后。
在調(diào)用setState()之后。
在調(diào)用didChangeDependencies()之后。
在State對象從樹中一個位置移除后(會調(diào)用deactivate)又重新插入到樹的其它位置之后。
reassemble():此回調(diào)是專門為了開發(fā)調(diào)試而提供的,在熱重載(hot reload)時會被調(diào)用,此回調(diào)在Release模式下永遠(yuǎn)不會被調(diào)用。
didUpdateWidget():在widget重新構(gòu)建時,F(xiàn)lutter framework會調(diào)用Widget.canUpdate來檢測Widget樹中同一位置的新舊節(jié)點,然后決定是否需要更新,如果Widget.canUpdate返回true則會調(diào)用此回調(diào)。正如之前所述,Widget.canUpdate會在新舊widget的key和runtimeType同時相等時會返回true,也就是說在在新舊widget的key和runtimeType同時相等時didUpdateWidget()就會被調(diào)用。
deactivate():當(dāng)State對象從樹中被移除時,會調(diào)用此回調(diào)。在一些場景下,F(xiàn)lutter framework會將State對象重新插到樹中,如包含此State對象的子樹在樹的一個位置移動到另一個位置時(可以通過GlobalKey來實現(xiàn))。如果移除后沒有重新插入到樹中則緊接著會調(diào)用dispose()方法。
dispose():當(dāng)State對象從樹中被永久移除時調(diào)用;通常在此回調(diào)中釋放資源。
StatefulWidget生命周期如圖3-2所示:

注意:在繼承StatefulWidget重寫其方法時,對于包含@mustCallSuper標(biāo)注的父類方法,都要在子類方法中先調(diào)用父類方法。