本篇主要介紹Flutter中的相關生命週期 分為 widget生命週期、app生命週期
Widget生命週期
flutter中widget主要分為 StatelessWidget 和 StatefulWidget 兩種 二者生命週期不太一樣
StatelessWidget(無狀態)
如果一個控制元件自身狀態不會去改變,建立了就直接顯示,不會有色值、大小或者其他屬性的變化,這種widget一般都是繼承自StatelessWidget,常見的有Container、ScrollView等,生命週期只有 build
class Frog extends StatelessWidget {
const Frog({ Key key }) : super(key: key);
@override
Widget build(BuildContext context) {
return new Container(color: const Color(0xFF2DBD3A));
}
}
複製程式碼
build是用來建立widget的,但是因為build在每次重新整理時候都會呼叫,通常需要把業務邏輯寫到建構函式中
StatefulWidget (有狀態)
需要持有狀態 State,這裡麵包含了一系列生命週期方法
class YellowBird extends StatefulWidget {
const YellowBird({ Key key }) : super(key: key);
@override
_YellowBirdState createState() => new _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
@override
Widget build(BuildContext context) {
return new Container(color: const Color(0xFFFFE306));
}
}
複製程式碼
官網示意圖如下
在網上看到一個更加下詳細的
大致可以劃分3個階段:
- 初始化
建構函式 > initState > didChangeDependencies > Widget build , 此時頁面載入完成。
- 狀態變化
- 元件移除
元件移除,例如頁面銷燬的時候會依次執行:deactivate > dispose
名稱 | 描述 | 呼叫次數 |
---|---|---|
createState | createState 是 StatefulWidget 裡建立 State 的方法,當要建立新的 StatefulWidget 的時候,會立即執行 createState,而且只執行一次 | 1次 |
initState | initState 是 StatefulWidget 建立完後呼叫的第一個方法,而且只執行一次,類似於 Android 的 onCreate、iOS 的 viewDidLoad(),所以在這裡 View 並沒有渲染,但是這時 StatefulWidget 已經被載入到渲染樹裡了,這時 StatefulWidget 的 mount的值會變為 true,直到 dispose呼叫的時候才會變為 false。可以在 initState裡做一些初始化的操作。 | 1次 |
didChangeDependencies | 1、當 StatefulWidget 第一次建立的時候,didChangeDependencies方法會在 initState方法之後立即呼叫,之後當 StatefulWidget 重新整理的時候,就不會呼叫了, 2、或者你的 StatefulWidget 依賴的 InheritedWidget 發生變化之後,didChangeDependencies才會呼叫,所以 didChangeDependencies有可能會被呼叫多次。 |
1次或多次 |
build | 在 StatefulWidget 第一次建立的時候,build方法會在 didChangeDependencies方法之後立即呼叫,另外一種會呼叫 build方法的場景是,每當 UI 需要重新渲染的時候(setState觸發),build都會被呼叫,所以 build會被多次呼叫,然後 返回要渲染的 Widget。千萬不要在 build裡做除了建立 Widget 之外的操作,因為這個會影響 UI 的渲染效率 | 多次 |
didUpdateWidget | 祖先節點rebuild widget時呼叫,當元件改變狀態時就會呼叫, 需要注意的是,涉及到controller的變更,需要在這個函式中移除老的controller的監聽,並建立新controller的監聽。 |
1次或多次 |
deactivate | 當要將 State 物件從渲染樹中移除的時候,就會呼叫 deactivate生命週期,這標誌著 StatefulWidget 將要銷燬,但是有時候 State 不會被銷燬,而是重新插入到渲染樹種 | 1次或多次 |
dispose | 當 View 不需要再顯示,從渲染樹中移除的時候,State 就會永久的從渲染樹中移除,就會呼叫 dispose生命週期,這時候就可以在 dispose裡做一些取消監聽、動畫的操作,和 initState是相反的 | 1次 |
這裡補充一個,**addPostFrameCallback,**是 StatefulWidge 渲染結束的回撥,只會被呼叫一次,之後 StatefulWidget 需要重新整理 UI 也不會被呼叫,addPostFrameCallback的使用方法是在 initState裡新增回撥:
import 'package:flutter/scheduler.dart';
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) => {});
}
複製程式碼
App生命週期
在 window.dart中有列舉類 AppLifecycleState
enum AppLifecycleState {
resumed,
inactive,
paused,
suspending,
}
複製程式碼
如果想要知道Flutter App的生命週期,比如前臺、後臺就需要使用**WidgetsBindingObserver **使用方法如下
State的類mix WidgetsBindingObserver,覆寫didChangeAppLifecycleState
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
@override
void initState(){
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.paused) {
// went to Background
}
if (state == AppLifecycleState.resumed) {
// came back to Foreground
}
}
}
複製程式碼
# 參考