老孟導(dǎo)讀:關(guān)于生命周期的文章共有2篇锋爪,一篇(此篇)是介紹 Flutter 中Stateful 組件的生命周期青伤。
第二篇是 Flutter 中與平臺相關(guān)的生命周期,
博客中還有更多精彩文章简烤,也歡迎加入 Flutter 交流群果覆。
此篇文章所說的生命周期與 StatefulWidget 組件的生命周期是不同的,這里平臺相關(guān)的生命周期指的是特定平臺相關(guān)操作所產(chǎn)生的生命周期夫否,比如 Android 中 App 退到后臺后的onPause等彻犁。
有人下場景,App正在播放視頻凰慈,此時回到手機桌面或者切換到其他App汞幢,那么此時視頻應(yīng)該暫停播放,F(xiàn)lutter 中使用 AppLifecycleState 實現(xiàn):
class AppLifecycle extends StatefulWidget {
@override
_AppLifecycleState createState() => _AppLifecycleState();
}
class _AppLifecycleState extends State<AppLifecycle>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
//TODO
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('App 生命周期'),
),
body: Center(
child: Text(''),
),
);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
重點是重寫 didChangeAppLifecycleState 方法微谓,AppLifecycleState 中的狀態(tài)包括:resumed森篷、inactive、paused堰酿、detached疾宏。
didChangeAppLifecycleState 方法的回調(diào)來源于系統(tǒng)的通知(notifications),正常情況下触创,App是能正常接收到這些通知坎藐,但有的情況下是無法接收到通知的,比如用戶強制關(guān)機哼绑、手機沒有電自動關(guān)機等岩馍。
下面對其狀態(tài)詳細說明:
- resumed:應(yīng)用程序可見且響應(yīng)用戶輸入。
- inactive:應(yīng)用程序處于非激活狀態(tài)抖韩,無法響應(yīng)用戶輸入蛀恩。在iOS上,打電話茂浮、響應(yīng)TouchID請求双谆、進入應(yīng)用程序切換器或控制中心都處于此狀態(tài)壳咕。在Android上,分屏應(yīng)用顽馋,打電話谓厘,彈出系統(tǒng)對話框或其他窗口等。
- pause:應(yīng)用程序不可見且無法響應(yīng)用戶輸入寸谜,運行在后臺竟稳。處于此狀態(tài)時,引擎將不會調(diào)用 Window.onBeginFrame 和 Window.onDrawFrame熊痴。
- detached:應(yīng)用程序仍寄存在Flutter引擎上他爸,但與平臺 View 分離。處于此狀態(tài)的時機:引擎首次加載到附加到一個平臺 View的過程中果善,或者由于執(zhí)行 Navigator pop 诊笤,view 被銷毀。
下面是關(guān)于生命周期經(jīng)常遇到的問題:
有2個頁面A和B岭埠,在B頁面點擊返回鍵返回到A盏混,didChangeAppLifecycleState 不回調(diào)
其實這個問題大部分人是想要實現(xiàn)類似于Android 中 onResume 中的功能蔚鸥,用 didChangeAppLifecycleState 是無法實現(xiàn)此功能的惜论,didChangeAppLifecycleState 是對應(yīng)于整個應(yīng)用程序的,而不是 Flutter 中 不同的路由(頁面)止喷。
從A->B馆类,在從B返回A,A重新加載數(shù)據(jù)使用如下方法:
A頁面代碼:
class A extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(onPressed: ()async{
var result = await Navigator.of(context).push(MaterialPageRoute(builder: (context){
return B();
}));
//從B返回到A時弹谁,執(zhí)行下面的代碼
//TODO 加載數(shù)據(jù)
});
}
}
B頁面代碼:
class B extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(onPressed: (){
Navigator.of(context).pop('返回的參數(shù)');
});
}
}
交流
老孟Flutter博客(330個控件用法+實戰(zhàn)入門系列文章):http://laomengit.com