Flutter完整開發(fā)實(shí)戰(zhàn)詳解(六球化、 深入Widget原理)

作為系列文章的第六篇,本篇主要在前文的探索下瓦糟,針對(duì)描述一下 Widget 中的一些有意思的原理筒愚。

文章匯總地址:

Flutter 完整實(shí)戰(zhàn)實(shí)戰(zhàn)系列文章專欄

Flutter 番外的世界系列文章專欄

首先我們需要明白,Widget 是什么菩浙?這里有一個(gè) “總所周知” 的答就是:Widget并不真正的渲染對(duì)象 巢掺。是的扯再,事實(shí)上在 Flutter 中渲染是經(jīng)歷了從 WidgetElement 再到 RenderObject 的過程。

我們都知道 Widget 是不可變的址遇,那么 Widget 是如何在不可變中去構(gòu)建畫面的熄阻?上面我們知道,Widget 是需要轉(zhuǎn)化為 Element 去渲染的倔约,而從下圖注釋可以看到秃殉,事實(shí)上 Widget 只是 Element 的一個(gè)配置描述 ,告訴 Element 這個(gè)實(shí)例如何去渲染浸剩。

image

那么 Widget 和 Element 之間是怎樣的對(duì)應(yīng)關(guān)系呢钾军?從上圖注釋也可知: Widget 和 Element 之間是一對(duì)多的關(guān)系 。實(shí)際上渲染樹是由 Element 實(shí)例的節(jié)點(diǎn)構(gòu)成的樹绢要,而作為配置文件的 Widget 可能被復(fù)用到樹的多個(gè)部分吏恭,對(duì)應(yīng)產(chǎn)生多個(gè) Element 對(duì)象。

那么RenderObject 又是什么重罪?它和上述兩個(gè)的關(guān)系是什么樱哼?從源碼注釋寫著 An object in the render tree 可以看出到 RenderObject 才是實(shí)際的渲染對(duì)象,而通過 Element 源碼我們可以看出:Element 持有 RenderObject 和 Widget剿配。

image

再結(jié)合下圖搅幅,可以大致總結(jié)出三者的關(guān)系是:配置文件 Widget 生成了 Element,而后創(chuàng)建 RenderObject 關(guān)聯(lián)到 Element 的內(nèi)部 renderObject 對(duì)象上呼胚,最后Flutter 通過 RenderObject 數(shù)據(jù)來布局和繪制茄唐。 理論上你也可以認(rèn)為 RenderObject 是最終給 Flutter 的渲染數(shù)據(jù),它保存了大小和位置等信息蝇更,F(xiàn)lutter 通過它去繪制出畫面沪编。

image

說到 RenderObject ,就不得不說 RenderBoxA render object in a 2D Cartesian coordinate system年扩,從源碼注釋可以看出蚁廓,它是在繼承 RenderObject 基礎(chǔ)的布局和繪制功能上,實(shí)現(xiàn)了“笛卡爾坐標(biāo)系”:以 Top常遂、Left 為基點(diǎn)纳令,通過寬高兩個(gè)軸實(shí)現(xiàn)布局和嵌套的。

RenderBox 避免了直接使用 RenderObject 的麻煩場(chǎng)景克胳,其中 RenderBox 的布局和計(jì)算大小是在 performLayout()performResize() 這兩個(gè)方法中去處理平绩,很多時(shí)候我們更多的是選擇繼承 RenderBox 去實(shí)現(xiàn)自定義。

綜合上述情況漠另,我們知道:

  • Widget只是顯示的數(shù)據(jù)配置捏雌,所以相對(duì)而言是輕量級(jí)的存在,而 Flutter 中對(duì) Widget 的也做了一定的優(yōu)化笆搓,所以每次改變狀態(tài)導(dǎo)致的 Widget 重構(gòu)并不會(huì)有太大的問題性湿。
  • RenderObject 就不同了纬傲,RenderObject 涉及到布局、計(jì)算肤频、繪制等流程叹括,要是每次都全部重新創(chuàng)建開銷就比較大了。

所以針對(duì)是否每次都需要?jiǎng)?chuàng)建出新的 Element 和 RenderObject 對(duì)象宵荒,Widget 都做了對(duì)應(yīng)的判斷以便于復(fù)用汁雷,比如:在 newWidgetoldWidgetruntimeTypekey 相等時(shí)會(huì)選擇使用 newWidget 去更新已經(jīng)存在的 Element 對(duì)象,不然就選擇重新創(chuàng)建新的 Element报咳。

由此可知:Widget 重新創(chuàng)建侠讯,Element 樹和 RenderObject 樹并不會(huì)完全重新創(chuàng)建。

看到這暑刃,說個(gè)題外話:那一般我們可以怎么獲取布局的大小和位置呢厢漩?

首先這里需要用到我們前文中提過的 GlobalKey ,通過 key 去獲取到控件對(duì)象的 BuildContext岩臣,而我們也知道 BuildContext 的實(shí)現(xiàn)其實(shí)是 Element溜嗜,而Element持有 RenderObject 。So婿脸,我們知道的 RenderObject 粱胜,實(shí)際上獲取到的就是 RenderBox ,那么通過 RenderBox 我們就只大小和位置了狐树。

  showSizes() {
    RenderBox renderBoxRed = fileListKey.currentContext.findRenderObject();
    print(renderBoxRed.size);
  }

  showPositions() {
    RenderBox renderBoxRed = fileListKey.currentContext.findRenderObject();
    print(renderBoxRed.localToGlobal(Offset.zero));
  }

--

自此,第六篇終于結(jié)束了鸿脓!(///▽///)

資源推薦

完整開源項(xiàng)目推薦:
我們還會(huì)再見嗎抑钟?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市野哭,隨后出現(xiàn)的幾起案子在塔,更是在濱河造成了極大的恐慌,老刑警劉巖拨黔,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛔溃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡篱蝇,警方通過查閱死者的電腦和手機(jī)贺待,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來零截,“玉大人麸塞,你說我怎么就攤上這事〗а茫” “怎么了哪工?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵奥此,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我雁比,道長(zhǎng)稚虎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任偎捎,我火速辦了婚禮蠢终,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鸭限。我一直安慰自己蜕径,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布败京。 她就那樣靜靜地躺著兜喻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赡麦。 梳的紋絲不亂的頭發(fā)上朴皆,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音泛粹,去河邊找鬼遂铡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晶姊,可吹牛的內(nèi)容都是我干的扒接。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼们衙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼钾怔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蒙挑,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤宗侦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后忆蚀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矾利,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年馋袜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了男旗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡桃焕,死狀恐怖剑肯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情观堂,我是刑警寧澤让网,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布呀忧,位于F島的核電站,受9級(jí)特大地震影響溃睹,放射性物質(zhì)發(fā)生泄漏而账。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一因篇、第九天 我趴在偏房一處隱蔽的房頂上張望泞辐。 院中可真熱鬧,春花似錦竞滓、人聲如沸咐吼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锯茄。三九已至,卻和暖如春茶没,著一層夾襖步出監(jiān)牢的瞬間肌幽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工抓半, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喂急,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓笛求,卻偏偏與公主長(zhǎng)得像廊移,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子探入,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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