flutter-State的生命周期

image.gif
  • initState:當(dāng)Widget第一次插入到Widget樹時會被調(diào)用萌业,對于每一個State對象坷襟,這個方法只會調(diào)用一次。所以生年,通常在該回調(diào)中做一些一次性的操作婴程,如一些初始化操作。(注意:不能在該回調(diào)中調(diào)用BuildContext.inheritFromWidgetOfExactType(該方法用于在Widget樹上獲取離當(dāng)前widget最近的一個父級InheritFromWidget)抱婉,原因是在初始化完成后档叔,Widget樹中的InheritFromWidget也可能會發(fā)生變化,所以正確的做法應(yīng)該在在build()方法或didChangeDependencies()中調(diào)用它蒸绩。)
  • didChangeDependencies():當(dāng)State對象的依賴發(fā)生變化時會被調(diào)用衙四;例如:在父widget的build() 中如果包含一個InheritedWidget,然后在之后InheritedWidget發(fā)生了變化患亿,那么此時InheritedWidget的子widget的didChangeDependencies()回調(diào)都會被調(diào)用传蹈。
  • build:它主要是用于構(gòu)建Widget子樹
  • 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é)點(diǎn)漱抓,然后決定是否需要更新表锻,如果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來實(shí)現(xiàn))。如果移除后沒有重新插入到樹中則緊接著會調(diào)用dispose()方法拷肌。
  • dispose:當(dāng)State對象從樹中被永久移除時調(diào)用到旦;通常在此回調(diào)中釋放資源旨巷。
class LifeCyclePage extends StatefulWidget {
  @override
  _LifeCyclePageState createState() => _LifeCyclePageState();

  @override
  StatefulElement createElement() {
    // print("page1--createElement");
    return super.createElement();
  }
}

class _LifeCyclePageState extends State<LifeCyclePage>
    with WidgetsBindingObserver {
  String title = "點(diǎn)擊我";

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    print('page1--initState');
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print(state.toString());
  }

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

  @override
  void didUpdateWidget(LifeCyclePage oldWidget) {
    print('page1--didUpdateWidget');
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    print('page1--build');
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text("生命周期示例"),
      ),
      body: Column(
        children: <Widget>[
          GestureDetector(
            child: new Text(title ?? ""),
            onTap: () {
              setState(() {
                title = "我變化了";
              });
            },
          ),
         ChildStatefulWidget(),
          FlatButton(
              color: Colors.grey,
              onPressed: () {
                Navigator.of(context)
                    .push(new MaterialPageRoute(builder: (BuildContext c) {
                  return new LifeCyclePage2();
                }));
              },
              child: Text("跳轉(zhuǎn)頁面")),
        ],
      ),
    );
  }

  @override
  void reassemble() {
    // TODO: implement reassemble
    super.reassemble();
    print('page1--reassemble');
  }

  @override
  void deactivate() {
    // TODO: implement deactivate
    super.deactivate();
    print('page1--deactivate');
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    //WidgetsBinding.instance.addObserver(this);
    print('page1--dispose');
  }
}

class ChildStatefulWidget extends StatefulWidget {
//  當(dāng)這個 Widget 首次插入到樹中時,框架會調(diào)用其 createState 函數(shù)以創(chuàng)建一個新的_ChildStatefulWidgetState實(shí)例來與該樹中的相應(yīng)位置關(guān)聯(lián)
//  當(dāng)這個widget的父級重建時添忘,父級將創(chuàng)建一個新的ChildStatefulWidget實(shí)例采呐,但是Flutter框架將重用已經(jīng)在樹中的_ChildStatefulWidgetState實(shí)例,
//  而不是再次調(diào)用createState創(chuàng)建一個新的State搁骑。
  @override
  _ChildStatefulWidgetState createState() {
    print("child--createState");
    return _ChildStatefulWidgetState();
  }
}

class _ChildStatefulWidgetState extends State<ChildStatefulWidget> {
  String title = "點(diǎn)擊我";

  @override
  Widget build(BuildContext context) {
    print('child--build');
    return GestureDetector(
      child: new Text(title ?? ""),
      onTap: () {
        setState(() {
          title = "我變化了";
        });
      },
    );
  }

  @override
  void initState() {
    print('child--initState');
    super.initState();
  }

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

  @override
  void didUpdateWidget(ChildStatefulWidget oldWidget) {
    print('child--didUpdateWidget');
    super.didUpdateWidget(oldWidget);
  }

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

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

  @override
  void dispose() {
    print('child--dispose');
    super.dispose();
    //WidgetsBinding.instance.addObserver(this);
  }
}

class LifeCyclePage2 extends StatefulWidget {
  @override
  _LifeCyclePageState createState(){
    return new _LifeCyclePageState();
  }

  @override
  StatefulElement createElement() {
    // TODO: implement createElement
//    print("page2--createElement");
    return super.createElement();
  }
}

class _LifeCyclePageState extends State<LifeCyclePage2> with WidgetsBindingObserver {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    print('page2---initState');
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print(state.toString());
  }

  @override
  void didChangeDependencies() {
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
    print('page2---didChangeDependencies');
  }

  @override
  void didUpdateWidget(LifeCyclePage2 oldWidget) {
    // TODO: implement didUpdateWidget
    super.didUpdateWidget(oldWidget);
    print('page2---didUpdateWidget');
  }

  @override
  Widget build(BuildContext context) {
    print('page2---build');
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text("生命周期示例2"),
      ),
    );
  }

  @override
  void reassemble() {
    // TODO: implement reassemble
    super.reassemble();
    print('page2---reassemble');
  }

  @override
  void deactivate() {
    // TODO: implement deactivate
    super.deactivate();
    print('page2---deactivate');
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    //WidgetsBinding.instance.addObserver(this);
    print('page2---dispose');
  }
}


進(jìn)入頁面1:
I/flutter (26059): page1--initState
I/flutter (26059): page1--didChangeDependencies
I/flutter (26059): page1--build
I/flutter (26059): child--createState
I/flutter (26059): child--initState
I/flutter (26059): child--didChangeDependencies
I/flutter (26059): child--build

點(diǎn)擊 第一個"點(diǎn)擊我": setState
I/flutter (26059): page1--build
I/flutter (26059): child--didUpdateWidget
I/flutter (26059): child--build

點(diǎn)擊 第二個"點(diǎn)擊我":
I/flutter (26059): child--build

跳轉(zhuǎn)頁面2:
I/flutter (26059): page2---initState
I/flutter (26059): page2---didChangeDependencies
I/flutter (26059): page2---build

返回頁面1:
I/flutter (26059): page2---deactivate
I/flutter (26059): page2---dispose

退出頁面1:
I/flutter (26059): page1--deactivate
I/flutter (26059): child--deactivate
I/flutter (26059): child--dispose
I/flutter (26059): page1--dispose

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斧吐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仲器,更是在濱河造成了極大的恐慌煤率,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乏冀,死亡現(xiàn)場離奇詭異蝶糯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辆沦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門裳涛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人众辨,你說我怎么就攤上這事端三。” “怎么了鹃彻?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵郊闯,是天一觀的道長。 經(jīng)常有香客問我蛛株,道長团赁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任谨履,我火速辦了婚禮欢摄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘笋粟。我一直安慰自己怀挠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布害捕。 她就那樣靜靜地躺著绿淋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尝盼。 梳的紋絲不亂的頭發(fā)上吞滞,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機(jī)與錄音盾沫,去河邊找鬼裁赠。 笑死殿漠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的佩捞。 我是一名探鬼主播凸舵,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼失尖!你這毒婦竟也來了啊奄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤掀潮,失蹤者是張志新(化名)和其女友劉穎菇夸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仪吧,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡庄新,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了薯鼠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片择诈。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖出皇,靈堂內(nèi)的尸體忽然破棺而出羞芍,到底是詐尸還是另有隱情,我是刑警寧澤郊艘,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布荷科,位于F島的核電站,受9級特大地震影響纱注,放射性物質(zhì)發(fā)生泄漏畏浆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一狞贱、第九天 我趴在偏房一處隱蔽的房頂上張望刻获。 院中可真熱鬧,春花似錦瞎嬉、人聲如沸蝎毡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顶掉。三九已至草娜,卻和暖如春挑胸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宰闰。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工茬贵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留簿透,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓解藻,卻偏偏與公主長得像老充,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子螟左,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容