做爲一個Android開發者,必定會對Activity的生命週期有這很深入的印象,而當你在使用Flutter時,其中Widget就是View,其生命週期就是從View建立到銷燬的過程。 Widget分爲StatelessWidgetStatefulWidget 兩種,這兩種Widget的生命週期分別以下。bash
無狀態Widget的生命週期很簡單,它只有一個生命週期:build網絡
build函數用來構建視圖,每次頁面刷新是被調用,典型的用法以下:app
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
child: new Text('Hello World'),
),
),
);
}
}
複製代碼
StatefulWidget生命週期整理以下圖:less
createState必須且僅執行一次,它用來建立state,當建立StatefulWidget時,該放方法被執行ide
在建立StatefulWidget後,initState是第一個被調用的方法,同createState同樣只被調用一次,此時widget的被添加至渲染樹,mount的值會變爲true,但並無渲染。能夠在該方法內作一些初始化操做。在在override時要低啊用super.initState()函數
@override
void initState() {
super.initState();
...
}
複製代碼
當widget第一次被建立時,didChangeDependencies緊跟着initState函數以後調用,在widget刷新時,該方法不會被調用。它會在「依賴」發生變化時被Flutter Framework調用,這個依賴是指widget是否使用父widget中InheritedWidget的數據。也便是隻有在widget依賴的InheritedWidget發生變化以後,didChangeDependencies纔會調用。 這種機制可使子組件在所依賴的InheritedWidget變化時來更新自身!好比當主題、locale(語言)等發生變化時,依賴其的子widget的didChangeDependencies方法將會被調用。ui
//經過繼承InheritedWidget,將當前計數器點擊次數保存在ShareDataWidget的data屬性中:
class ShareDataWidget extends InheritedWidget {
ShareDataWidget({
@required this.data,
Widget child
}) :super(child: child);
final int data; //須要在子樹中共享的數據,保存點擊次數
//定義一個便捷方法,方便子樹中的widget獲取共享數據
static ShareDataWidget of(BuildContext context) {
return context.inheritFromWidgetOfExactType(ShareDataWidget);
}
//該回調決定當data發生變化時,是否通知子樹中依賴data的Widget
@override
bool updateShouldNotify(ShareDataWidget old) {
//若是返回true,則子樹中依賴(build函數中有調用)本widget
//的子widget的`state.didChangeDependencies`會被調用
return old.data != data;
}
}
class _TestWidget extends StatefulWidget {
@override
__TestWidgetState createState() => new __TestWidgetState();
}
//而後咱們實現一個子組件_TestWidget,在其build方法中引用ShareDataWidget中的數據。
class __TestWidgetState extends State<_TestWidget> {
@override
Widget build(BuildContext context) {
//使用InheritedWidget中的共享數據
return Text(ShareDataWidget
.of(context)
.data
.toString());
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
//父或祖先widget中的InheritedWidget改變(updateShouldNotify返回true)時會被調用。
//若是build中沒有依賴InheritedWidget,則此回調不會被調用。
print("Dependencies change");
}
}
複製代碼
注意:若是_TestWidget的build方法中沒有使用ShareDataWidget的數據,那麼它的didChangeDependencies()將不會被調用,由於它並無依賴ShareDataWidget。在依賴改變以後build方法也會被調用,因此在大多數場景下都無需使用didChangeDependencies。然而若是你須要在依賴改變後執行一些昂貴的操做,好比網絡請求,這時最好的方式就是在此方法中執行,這樣能夠避免每次build()都執行這些昂貴操做。this
build函數會在widget第一次建立時緊跟着didChangeDependencies方法以後和UI從新渲染是時調用。build只作widget的建立操做,若是在build裏作其餘操做,會影響UI的渲染效果spa
當組件的狀態改變的時候就會調用didUpdateWidget,好比調用了setState.code
當要將State對象從渲染樹中移除的時候,就會調用 deactivate 生命週期,這標誌着 StatefulWidget將要銷燬。頁面切換時,也會調用它,由於此時State在視圖樹中的位置發生了變化可是State不會被銷燬,而是從新插入到渲染樹中。 重寫的時候必需要調用 super.deactivate()
從渲染樹中移除view的時候調用,State會永久的從渲染樹中移除,和initState正好相反mount值變味false。這時候就能夠在dispose裏作一些取消監聽操做。
函數 | 調用次數 | 調用時間 |
---|---|---|
createState | 1 | 第一次建立 |
initState | 1 | 第一次建立 |
didChangeDependencies | n | 第一次建立和依賴變化時 |
build | n | 第一次建立和UI從新渲染時 |
didUpdateWidget | n | 第一次建立和UI從新渲染時 |
deactivate | n | state對象將要移除時 |
dispose | 1 | state對象移除 |