Flutter中key的作用

文章來源于Flutter Widgets 101 Ep. 4,感興趣的同學可以直接看視頻塘雳,更便于理解陆盘。

首先,我們要明白Key的作用败明,Keys preserve state when widgets move around in your widget tree. They can be used to preserve the user's scroll location, or keeping state when modifying a collection. (當組件在組件樹中移動時使用Key可以保持組件之前的狀態(tài)隘马,比如在用戶滑動時或者集合改變時),這是一個抽象的定義妻顶,大家盡量理解原文酸员,在后面的例子中可以很好的理解。

什么時候使用Key讳嘱?

我們參照視頻幔嗦,寫下了如下Demo,當點擊FloatingActionButton時,交換兩個Widget的位置沥潭。(你可以下載項目邀泉,運行一下,會更便于理解)

image.png

  1. 當我們使用Stateless Widget時,widget可以正常的移動汇恤。swap_color_1.dart
  2. 當我們把Widget改為Stateful時庞钢,交換出現(xiàn)了問題。swap_color_2.dart
  3. 當我們?yōu)镾tateful加入Key之后因谎,程序又能正常的執(zhí)行swap_color_3.dart

從Demo中我們可以看出基括,當使用Stateless Widget時,我們并不需要使用key财岔,當使用Stateful Widget時阱穗,集合內(nèi)有數(shù)據(jù)移動和改變并且需要展示到界面時才需要key。

Key應(yīng)該用到哪使鹅?

首先我們來搞懂上面揪阶,為什么swap_color_2會出問題,要明白這個問題患朱,我們需要明白Flutter的渲染策略鲁僚。

我們在構(gòu)建Flutter的UI時是以Widget的形式『拼接』出來的,組件樹作為UI每一個組件都對應(yīng)一個元素(原文中是Slot)裁厅,從而形成了『元素樹』(Element Tree)冰沙,元素樹的內(nèi)容非常簡單,只包含了組件的類型和子元素的引用(Type)执虹,你可以把元素樹當做Flutter App中的骨架(skeleton),它只展現(xiàn)了App的結(jié)構(gòu)拓挥,并不包含其他具體的信息。

當我們交換組件樹中的元素時袋励,組件確實進行了交換侥啤,但是元素樹卻不一定。Flutter會先遍歷(walk)整個元素樹茬故,從Row上的主元素盖灸,到主元素的子元素,查看整體的結(jié)構(gòu)是否發(fā)生了變化磺芭,當然赁炎,它檢查的只能是元素的Type和Key,在給出的例子中钾腺,當我們不設(shè)置Key時徙垫,元素樹對比Type,發(fā)現(xiàn)Type并沒有發(fā)生變化放棒,而Flutter卻是用元素樹和元素對應(yīng)的狀態(tài)(可用或者不可用)姻报,來決定這個元素是否應(yīng)該顯示出來,所以在界面中并沒有發(fā)生改變哨查,但是當我們加入Key之后逗抑,對比的對象多了一個,并且是和之前不一樣的寒亥,F(xiàn)lutter察覺到之后邮府,立即改變了元素的狀態(tài),讓它變?yōu)椤簾o用狀態(tài)』(deactivate)溉奕,當遍歷完之后褂傀,F(xiàn)lutter會瀏覽(look through)這些不匹配的元素(non-matched children)通過相應(yīng)的引用為之找到對應(yīng)的組件。當所有的元素都匹配完成之后加勤,F(xiàn)lutter會刷新界面仙辟,展現(xiàn)出我們預想的。


Widget Tree and Element Tree

那么Key到底應(yīng)該用到哪呢鳄梅?
我們再來一個例子叠国,swap_color_4,我們把色塊用Padding包裝一下戴尸。運行之后會發(fā)現(xiàn)粟焊,色塊并沒有交換,而是以隨機的形式在變換顏色孙蒙。為什么呢项棠?

Padding Stateful

結(jié)合我們上面的理論,我們分析一下這次的Widget Tree 和 Element Tree挎峦,當我們交換元素后香追,F(xiàn)lutter element-to-widget matching algorithm,(元素-組件匹配算法),開始進行對比坦胶,算法每次只對比一層透典,即Padding這一層。顯然顿苇,Padding并沒有發(fā)生本質(zhì)的變化掷匠。
Padding Widget Tree

于是開始進行第二層對比,在對比時Flutter發(fā)現(xiàn)元素與組件的Key并不匹配岖圈,于是讹语,把它設(shè)置成不可用狀態(tài),但是這里所使用的Key只是本地Key(Local Key)蜂科,F(xiàn)lutter并不能找到另一層里面的Key(即另外一個Padding Widget中的Key)所以顽决,F(xiàn)lutter就創(chuàng)建了一個新的Widget,而這個Widget的顏色就成了我們看到的『隨機色』导匣。


Stateful Widget Tree

通過上面的示例才菠,我們能明顯的看出,我們的Key要設(shè)置到組件樹的 頂層贡定,而這一層在改變時赋访,才能復用或者更新狀態(tài)。

用哪一種Key?

Flutter中有很多Key蚓耽,但是總體分為兩種 Local Key和Global Key兩種渠牲。


Key UML

對于Key的研究還不是特別多,有時間再補一篇步悠,上面的例子签杈,因為沒有數(shù)據(jù),所以使用了UniqueKey鼎兽,在真實的開發(fā)中答姥,我們可以用Model中的id作為ObjectKey。

GlobalKey其實是對應(yīng)于LocalKey谚咬,上面我們說Padding中的就是LocalKey鹦付,Global即可以在多個頁面或者層級復用,比如兩個頁面也可也同時保持一個狀態(tài)择卦。

還處在學習Flutter狀態(tài)敲长,如有錯誤請您及時指正,謝謝互捌。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末潘明,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秕噪,更是在濱河造成了極大的恐慌钳降,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腌巾,死亡現(xiàn)場離奇詭異遂填,居然都是意外死亡,警方通過查閱死者的電腦和手機澈蝙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門吓坚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人灯荧,你說我怎么就攤上這事礁击。” “怎么了逗载?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵哆窿,是天一觀的道長。 經(jīng)常有香客問我厉斟,道長挚躯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任擦秽,我火速辦了婚禮码荔,結(jié)果婚禮上漩勤,老公的妹妹穿的比我還像新娘。我一直安慰自己缩搅,他們只是感情好越败,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著誉己,像睡著了一般眉尸。 火紅的嫁衣襯著肌膚如雪域蜗。 梳的紋絲不亂的頭發(fā)上巨双,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音霉祸,去河邊找鬼筑累。 笑死,一個胖子當著我的面吹牛丝蹭,可吹牛的內(nèi)容都是我干的慢宗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼奔穿,長吁一口氣:“原來是場噩夢啊……” “哼镜沽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贱田,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤缅茉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后男摧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔬墩,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年耗拓,在試婚紗的時候發(fā)現(xiàn)自己被綠了拇颅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡乔询,死狀恐怖樟插,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情竿刁,我是刑警寧澤黄锤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布愚隧,位于F島的核電站昧诱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谭梗。R本人自食惡果不足惜监婶,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一旅赢、第九天 我趴在偏房一處隱蔽的房頂上張望齿桃。 院中可真熱鬧,春花似錦煮盼、人聲如沸短纵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽香到。三九已至,卻和暖如春报破,著一層夾襖步出監(jiān)牢的瞬間悠就,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工充易, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梗脾,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓盹靴,卻偏偏與公主長得像炸茧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子稿静,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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