Flutter-State生命周期

  1. State 的生命周期和 StatefulWidget 不同餐禁,當(dāng) StatefulWidget 狀態(tài)改變后就會(huì)被重建,但是 State 不會(huì)改變突照,但是當(dāng) StatefulWidget 在 View 樹(shù)中移除再插入又會(huì)生成新的 State帮非。參考下文 State.context.
  2. initState -> build -> 狀態(tài)改變 -> didUpdateWidget -> build --->移除.

在學(xué)習(xí) flutter 的時(shí)候,總會(huì)用到 StatefulWidget,它是一個(gè)有狀態(tài)的 widget末盔,會(huì)根據(jù)不同狀態(tài)有不同顯示筑舅,它的生命周期與 State 有關(guān),它的基本寫(xiě)法如下

// flutter官方教程里面的一個(gè)類陨舱,點(diǎn)擊一個(gè)關(guān)注的星星翠拣,然后就表明已經(jīng)關(guān)注。再點(diǎn)擊表示不再關(guān)注游盲,默認(rèn)狀態(tài)是已關(guān)注误墓,關(guān)注數(shù)是41
class FavoriteWidget extends StatefulWidget {
  @override
  _FavoriteWidgetState createState() => new _FavoriteWidgetState();
}
class _FavoriteWidgetState extends State<FavoriteWidget> {
  bool _isFavorited = true;
  int _favoriteCount = 41;

  void _toggleFavorite() {
    setState(() {
      // If the lake is currently favorited, unfavorite it. Otherwise, favorite it.
        _favoriteCount = _isFavorited?_favoriteCount -1:_favoriteCount +1 ;
        _isFavorited = !_isFavorited;
    });
  }
  @override
  Widget build(BuildContext context) {
    return new Widget(
        // build by states
    );
  }
}

將 FavoriteWidget 插入到 Views 樹(shù)中的時(shí)候,每當(dāng)調(diào)用 States.setState() 時(shí)益缎,都會(huì)重新build一次FavoriteWidget 谜慌,然后將新的 Views代替原先的,并顯示給用戶莺奔。

您可能想知道為什么 StatefulWidget 和 State 是單獨(dú)的對(duì)象欣范。在 Flutter 中,這兩種類型的對(duì)象具有不同的生命周期: Widget 是臨時(shí)對(duì)象令哟,用于構(gòu)建當(dāng)前狀態(tài)下的應(yīng)用程序恼琼,而 State 對(duì)象在多次調(diào)用build()之間保持不變,允許它們記住信息(狀態(tài))励饵。

State的生命周期

image

總體介紹一下生命周期驳癌,大致可以看成三個(gè)階段:

  • 初始化(插入渲染樹(shù))
  • 狀態(tài)改變(在渲染樹(shù)中存在)
  • 銷毀(從渲染樹(shù)種移除)

先舉 FavoriteWidget 為例,當(dāng)這個(gè) Widget 首次插入到樹(shù)中時(shí)役听,框架會(huì)調(diào)用其 createState 函數(shù)以創(chuàng)建一個(gè)新的_FavoriteWidgetState實(shí)例來(lái)與該樹(shù)中的相應(yīng)位置關(guān)聯(lián)(請(qǐng)注意颓鲜,我們通常命名State子類時(shí)帶一個(gè)下劃線,這表示其是私有的)典予。 當(dāng)這個(gè)widget的父級(jí)重建時(shí)甜滨,父級(jí)將創(chuàng)建一個(gè)新的FavoriteWidget實(shí)例,但是Flutter框架將重用已經(jīng)在樹(shù)中的_FavoriteWidgetState實(shí)例瘤袖,而不是再次調(diào)用createState創(chuàng)建一個(gè)新的衣摩。

從 StatefulWidget調(diào)用createState之后,框架將新的狀態(tài)對(duì)象插入樹(shù)中捂敌,然后調(diào)用 State 的initState艾扮,接著如上圖所示走了一遍自身的生命周期。需要注意的是占婉,StatefulWidget 和 State 是不同的生命周期。

生命周期詳解

initState

當(dāng)插入渲染樹(shù)的時(shí)候調(diào)用逆济,這個(gè)函數(shù)在生命周期中只調(diào)用一次磺箕。這里可以做一些初始化工作抛虫,比如初始化State的變量松靡。

didChangeDependencies

這個(gè)函數(shù)會(huì)緊跟在initState之后調(diào)用,并且可以調(diào)用BuildContext.inheritFromWidgetOfExactType建椰,那么BuildContext.inheritFromWidgetOfExactType的使用場(chǎng)景是什么呢?

 static TabController of(BuildContext context) {
    final _TabControllerScope scope = context.inheritFromWidgetOfExactType(_TabControllerScope);
    return scope?.controller;
  }

實(shí)際上就是調(diào)用BuildContext.inheritFromWidgetOfExactType阅茶,也就說(shuō)在didChangeDependencies中,可以跨組件拿到數(shù)據(jù)谅海。

didUpdateWidget

當(dāng)組件的狀態(tài)改變的時(shí)候就會(huì)調(diào)用didUpdateWidget,比如調(diào)用了setState.

實(shí)際上這里flutter框架會(huì)創(chuàng)建一個(gè)新的Widget,綁定本State脸哀,并在這個(gè)函數(shù)中傳遞老的Widget。

這個(gè)函數(shù)一般用于比較新扭吁、老Widget,看看哪些屬性改變了侥袜,并對(duì)State做一些調(diào)整。

需要注意的是浦旱,涉及到controller的變更九杂,需要在這個(gè)函數(shù)中移除老的controller的監(jiān)聽(tīng),并創(chuàng)建新controller的監(jiān)聽(tīng)例隆。


image

image

deactivate

在dispose之前镀层,會(huì)調(diào)用這個(gè)函數(shù)。

dispose

一旦到這個(gè)階段唱逢,組件就要被銷毀了,這個(gè)函數(shù)一般會(huì)移除監(jiān)聽(tīng)备韧,清理環(huán)境《⒑‘

總結(jié)

階段 調(diào)用次數(shù)
構(gòu)造函數(shù) 1
initState 1
didChangeDependencies >=1
didUpdateWidget >=1
deactivate >=1
dispose 1

各個(gè)方法的解釋:

  • initState:插入渲染樹(shù)時(shí)調(diào)用捧挺,只調(diào)用一次闽烙,widget創(chuàng)建執(zhí)行的第一個(gè)方法,可以再里面初始化一些數(shù)據(jù),以及綁定控制器
  • didChangeDependencies:當(dāng)State對(duì)象的依賴發(fā)生變化時(shí)會(huì)被調(diào)用疏旨;例如:在之前build() 中包含了一個(gè)InheritedWidget,然后在之后的build() 中InheritedWidget發(fā)生了變化遏匆,那么此時(shí)InheritedWidget的子widget的didChangeDependencies()回調(diào)都會(huì)被調(diào)用谁榜。InheritedWidget這個(gè)widget可以由父控件向子控件共享數(shù)據(jù),案例可以參考 scoped_model開(kāi)源庫(kù)帝蒿。
  • build :它主要是用于構(gòu)建Widget子樹(shù)的巷怜,調(diào)用次數(shù):多次,初始化之后開(kāi)始繪制界面延塑,當(dāng)setState觸發(fā)的時(shí)候會(huì)再次被調(diào)用
  • didUpdateWidget:組件狀態(tài)改變時(shí)候調(diào)用,可能會(huì)調(diào)用多次
  • deactivate:當(dāng) State 被暫時(shí)從視圖樹(shù)中移除時(shí)胖替,會(huì)調(diào)用這個(gè)函數(shù)豫缨。
    頁(yè)面切換時(shí),也會(huì)調(diào)用它好芭,因?yàn)榇藭r(shí) State 在視圖樹(shù)中的位置發(fā)生了變化,需要先暫時(shí)移除后添加招狸。
  • dispose():當(dāng)State對(duì)象從樹(shù)中被永久移除時(shí)調(diào)用;通常在此回調(diào)中釋放資源裙戏。
  • reassemble:此回調(diào)是專門(mén)為了開(kāi)發(fā)調(diào)試而提供的,在熱重載(hot reload)時(shí)會(huì)被調(diào)用营勤,此回調(diào)在Release模式下永遠(yuǎn)不會(huì)被調(diào)用壹罚。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赂蠢,隨后出現(xiàn)的幾起案子辨泳,更是在濱河造成了極大的恐慌,老刑警劉巖漠吻,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件途乃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡耍共,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)杠纵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)钩骇,“玉大人,你說(shuō)我怎么就攤上這事银亲∨Τ祝” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵馏段,是天一觀的道長(zhǎng)轩拨。 經(jīng)常有香客問(wèn)我院喜,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任元咙,我火速辦了婚禮巫员,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘简识。我一直安慰自己,他們只是感情好奢赂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布颈走。 她就那樣靜靜地躺著,像睡著了一般轧钓。 火紅的嫁衣襯著肌膚如雪锐膜。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天道盏,我揣著相機(jī)與錄音,去河邊找鬼牺堰。 笑死颅围,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的院促。 我是一名探鬼主播斧抱,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辉浦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼茎辐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起拖陆,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤依啰,失蹤者是張志新(化名)和其女友劉穎乎串,沒(méi)想到半個(gè)月后速警,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡长豁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年蕉斜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缀棍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爬范,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出璧亮,到底是詐尸還是另有隱情斥难,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布群扶,位于F島的核電站,受9級(jí)特大地震影響竞阐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骆莹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一幕垦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧先改,春花似錦、人聲如沸盏道。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)朗伶。三九已至步咪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間点晴,已是汗流浹背悯周。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留禽翼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓锐墙,卻偏偏與公主長(zhǎng)得像长酗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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