Flutter:State生命周期以及頁面重載問題詳解

1.流程圖

1600828878156.jpg

2.上代碼

這里需要混入WidgetsBindingObserver,重寫didChangeAppLifecycleState方法才能看到app進入前后臺的狀態(tài)

class _HomeItemPageState extends State<HomeItemPage>
    with WidgetsBindingObserver {
  @override
  void initState() {
    print('_HomeItemPageState initState');
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeDependencies() {
    print('_HomeItemPageState didChangeDependencies');
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    print('_HomeItemPageState build');
    return Container(
      padding: EdgeInsets.all(10),
      child: Column(
        children: [
          Text('首頁'),
          Text('num:$_count'),
          RaisedButton(
            onPressed: () {
              _count++;
              setState(() {});
            },
            child: Text('num++'),
          ),
          RaisedButton(
            onPressed: () {
              Navigator.pushNamed(context, Constant.homeHomePage);
            },
            child: Text('下一個頁面'),
          ),
          RaisedButton(
            onPressed: () {
              setState(() {

              });
            },
            child: Text('刷新頁面'),
          ),
        ],
      ),
    );
  }

  @override
  void deactivate() {
    super.deactivate();
    print('_HomeItemPageState deactivate');
  }

  @override
  void didUpdateWidget(HomeItemPage oldWidget) {
    print('_HomeItemPageState didUpdateWidget');
    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
    print('_HomeItemPageState dispose');
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void reassemble() {
    super.reassemble();
    print('_HomeItemPageState reassemble');
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print('_HomeItemPageState didChangeAppLifecycleState $state');
    super.didChangeAppLifecycleState(state);
  }

3.日志

我這邊使用的是一個嵌套行頁面,主頁面(TabBarViewPage)是一個TabBar+TabBarView實現(xiàn)的子頁面切換,子頁面是三個頁面(HomeItemPage,EmailItemPage,MineItemPage)


1600829390232.jpg

當(dāng)頁面創(chuàng)建的時候

I/flutter (25213): _TabBarViewPageState initState
I/flutter (25213): _TabBarViewPageState didChangeDependencies
I/flutter (25213): _TabBarViewPageState build
I/flutter (25213): _HomeItemPageState initState
I/flutter (25213): _HomeItemPageState didChangeDependencies
I/flutter (25213): _HomeItemPageState build

當(dāng)內(nèi)部子頁面切換的時候

子頁面互相切換的時候下一個頁面創(chuàng)建,上一個頁面就會被銷毀,這是flutter默認(rèn)的情況,頁面會被移除然后重載。當(dāng)然你也可以設(shè)置需要的頁面不被重載的頁面,這個后面再講

I/flutter (25213): _tabController.addListener
I/flutter (25213): _EmailItemPageState initState
I/flutter (25213): _EmailItemPageState didChangeDependencies
I/flutter (25213): _EmailItemPageState build
I/flutter (25213): _tabController.addListener
I/flutter (25213): _HomeItemPageState deactivate
I/flutter (25213): _HomeItemPageState dispose
I/flutter (25213): _tabController.addListener
I/flutter (25213): _MineItemPageState initState
I/flutter (25213): _MineItemPageState didChangeDependencies
I/flutter (25213): _MineItemPageState build
I/flutter (25213): _tabController.addListener
I/flutter (25213): _EmailItemPageState deactivate
I/flutter (25213): _EmailItemPageState dispose

當(dāng)刷新當(dāng)前頁面的時候

I/flutter (25213): _HomeItemPageState build

當(dāng)跳轉(zhuǎn)新頁面在返回的時候

I/flutter (25213): _TabBarViewPageState didChangeDependencies
I/flutter (25213): _TabBarViewPageState build
I/flutter (25213): _TabBarViewPageState didChangeDependencies
I/flutter (25213): _TabBarViewPageState build

當(dāng)頁面進入后臺在返回的時候

I/flutter (25213): _TabBarViewPageState didChangeAppLifecycleState AppLifecycleState.inactive
I/flutter (25213): _HomeItemPageState didChangeAppLifecycleState AppLifecycleState.inactive
I/flutter (25213): _TabBarViewPageState didChangeAppLifecycleState AppLifecycleState.paused
I/flutter (25213): _HomeItemPageState didChangeAppLifecycleState AppLifecycleState.paused
I/flutter (25213): _TabBarViewPageState didChangeAppLifecycleState AppLifecycleState.inactive
I/flutter (25213): _HomeItemPageState didChangeAppLifecycleState AppLifecycleState.inactive
I/flutter (25213): _TabBarViewPageState didChangeAppLifecycleState AppLifecycleState.resumed
I/flutter (25213): _HomeItemPageState didChangeAppLifecycleState AppLifecycleState.resumed

app熱重載的時候

I/flutter (25213): _TabBarViewPageState reassemble
I/flutter (25213): _HomeItemPageState reassemble
I/flutter (25213): _TabBarViewPageState didUpdateWidget
I/flutter (25213): _TabBarViewPageState build
I/flutter (25213): _HomeItemPageState didUpdateWidget
I/flutter (25213): _HomeItemPageState build

主頁頁面銷毀

I/flutter (25213): _TabBarViewPageState deactivate
I/flutter (25213): _HomeItemPageState deactivate
I/flutter (25213): _HomeItemPageState dispose
I/flutter (25213): _TabBarViewPageState dispose

4.各回調(diào)方法解析

  • initState:State對象載入,可以在里面做一些數(shù)據(jù)初始化等
  • didChangeDependencies:當(dāng)State對象的依賴發(fā)生變化時會被調(diào)用
  • build :頁面構(gòu)建
  • reassemble:在熱重載時調(diào)用,Release模式下不會被調(diào)用。
  • didUpdateWidget:頁面重新buid的時候會調(diào)用該方法。
  • deactivate:當(dāng)State對象被移除時,會調(diào)用此回調(diào)。
  • dispose:當(dāng)State對象被移除時調(diào)用,通常在此回調(diào)中釋放資源。

5.頁面重載問題

解決頁面重載需要三步

  • 混入(with)AutomaticKeepAliveClientMixin<T extends StatefulWidget>
  • build方法添加super.build(context)
  • 重寫wantKeepAlive返回true
    (注意這里是對不需要重載的頁面添加,就是對TabBarView里的頁面,不是對主頁面添加,網(wǎng)上有大多博文都是錯誤的)
    (對混入(with)不了解的可以看一下這個文章Flutter(Dart)中extends 、 implements 、 with的用法與區(qū)別
    我們將_HomeItemPageState混入AutomaticKeepAliveClientMixin看看效果
    上代碼
class _HomeItemPageState extends State<HomeItemPage>
    with WidgetsBindingObserver, AutomaticKeepAliveClientMixin<HomeItemPage> 

 Widget build(BuildContext context) {
    super.build(context);

  @override
  bool get wantKeepAlive => true;

當(dāng)子頁面切換時(home切換mail再返回home再切換mail)

可以看到home并沒有被銷毀也沒有重載,但是mail被銷毀了然后重載了

I/flutter (25213): _TabBarViewPageState initState
I/flutter (25213): _TabBarViewPageState didChangeDependencies
I/flutter (25213): _TabBarViewPageState build
I/flutter (25213): _HomeItemPageState initState
I/flutter (25213): _HomeItemPageState didChangeDependencies
I/flutter (25213): _HomeItemPageState build
I/flutter (25213): _tabController.addListener
I/flutter (25213): _EmailItemPageState initState
I/flutter (25213): _EmailItemPageState didChangeDependencies
I/flutter (25213): _EmailItemPageState build
I/flutter (25213): _tabController.addListener
I/flutter (25213): _tabController.addListener
I/flutter (25213): _tabController.addListener
I/flutter (25213): _EmailItemPageState deactivate
I/flutter (25213): _EmailItemPageState dispose
I/flutter (25213): _tabController.addListener
I/flutter (25213): _EmailItemPageState initState
I/flutter (25213): _EmailItemPageState didChangeDependencies
I/flutter (25213): _EmailItemPageState build
I/flutter (25213): _tabController.addListener

主頁頁面銷毀

可以看到當(dāng)主頁面銷毀的時候,home也是被銷毀的

I/flutter (25213): _TabBarViewPageState deactivate
I/flutter (25213): _HomeItemPageState deactivate
I/flutter (25213): _HomeItemPageState dispose
I/flutter (25213): _TabBarViewPageState dispose

代碼下載

Github源代碼

更多Flutter學(xué)習(xí)請移步

Flutter入門教學(xué)目錄持續(xù)更新中

Github源代碼持續(xù)更新中

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容