為您解碼網(wǎng)站建設(shè)的點(diǎn)點(diǎn)滴滴
發(fā)表日期:2018-07 文章編輯:小燈 瀏覽次數(shù):2377
作者:閑魚技術(shù)-朝空
本文不是flutter界面開發(fā)入門文章,而是一篇深入介紹Flutter framework關(guān)于視圖樹的創(chuàng)建與管理機(jī)制、布局、渲染的原理、以及flutter布局與渲染相關(guān)性能優(yōu)化的設(shè)計(jì)思路的文章。同時(shí)介紹在使用flutter開發(fā)過程中,遇到的一些坑和相應(yīng)的解決方案。
本文主要介紹build、layout、paint的三個(gè)階段
flutter視圖樹包含了三種樹,上圖只是介紹了三顆樹的基礎(chǔ)class的對(duì)應(yīng)關(guān)系和功能介紹
調(diào)用runApp(rootWidget),將rootWidget傳給rootElement,做為rootElement的子節(jié)點(diǎn),生成Element樹,由Element樹生成Render樹
flutter界面開發(fā)是一種響應(yīng)式編程,主張simple is fast,flutter設(shè)計(jì)的初衷希望數(shù)據(jù)變更時(shí)發(fā)送通知到對(duì)應(yīng)的可變更節(jié)點(diǎn)(可能是一個(gè)StatefullWidget子節(jié)點(diǎn),也可以是rootWidget),由上到下重新create widget樹進(jìn)行刷新,這種思路比較簡(jiǎn)單,不用關(guān)心數(shù)據(jù)變更會(huì)影響到哪些節(jié)點(diǎn)。
widget只是一個(gè)配置數(shù)據(jù)結(jié)構(gòu),創(chuàng)建是非常輕量的,加上flutter團(tuán)隊(duì)對(duì)widget的創(chuàng)建/銷毀做了優(yōu)化,不用擔(dān)心整個(gè)widget樹重新創(chuàng)建所帶來的性能問題,但是renderobject就不一樣了,renderobject涉及到layout、paint等復(fù)雜操作,是一個(gè)真正渲染的view,整個(gè)view 樹重新創(chuàng)建開銷就比較大,所以答案是否定的。
注意事項(xiàng):
注意事項(xiàng):
數(shù)據(jù)從根往下傳數(shù)據(jù),常規(guī)做法是一層層往下,當(dāng)深度變大,數(shù)據(jù)的傳輸變的困難,flutter提供InheritedWidget用于子節(jié)點(diǎn)向祖先節(jié)點(diǎn)獲取數(shù)據(jù)的機(jī)制,如下例子:
class FrogColor extends InheritedWidget {const FrogColor({Key key,@required this.color,@required Widget child,}) : assert(color != null), assert(child != null), super(key: key, child: child); final Color color; static FrogColor of(BuildContext context) {return context.inheritFromWidgetOfExactType(FrogColor);} @overridebool updateShouldNotify(FrogColor old) => color != old.color; }
child及其以下的節(jié)點(diǎn)可以通過調(diào)用下面的接口讀取color數(shù)據(jù)
FrogColor.of(context).color
說明:BuildContext 就是Element的一個(gè)接口類
imagecontext.inheritFromWidgetOfExactType(FrogColor)其實(shí)是通過context/element往上遍歷樹,查找到第一個(gè)FrogColor的祖先節(jié)點(diǎn),取該節(jié)點(diǎn)的widget對(duì)象
子節(jié)點(diǎn)狀態(tài)變更,向上上報(bào)通過發(fā)送通知的方式
Notification(data).dispatch(context)
parent傳入約束條件,在dramframe的layout階段,child根據(jù)自身的渲染內(nèi)容返回size
問題:在build()階段獲取不到size,很多時(shí)候需要提前知道部分widget size來進(jìn)行布局,解決方案當(dāng)widget 在對(duì)應(yīng)renderobject的layout階段之后,發(fā)送一個(gè)LayoutChangeNotification,參考SizeChangedLayoutNotifier class,但是SizeChangedLayoutNotifier沒有上報(bào)init layout size,可以自己參考這個(gè)實(shí)現(xiàn)封裝一個(gè)Notifier
renderObject在layout階段做了Relayout boundary的優(yōu)化,當(dāng)子樹進(jìn)行relayout時(shí),滿足下面三種中的一種
那么該renderObject設(shè)置為Relayout boundary,也就是該renderObject的重新layout不觸發(fā)parent的layout,一般情況下開發(fā)人員不需要關(guān)心Relayout boundary,除非是使用CustomMultiChildLayout
iOS的每一個(gè)UIView都有一個(gè)layer,flutter的render object不一定存在layer,一般情況下一個(gè)renderObject子樹都渲染在一個(gè)layer上,那么什么renderObject具有l(wèi)ayer,子renderObject怎么渲染到這個(gè)layer?
alwaysNeedsCompositing == true
或者isRepaintBoundary == true
,renderOject會(huì)有對(duì)應(yīng)的compositing layer子renderObject會(huì)對(duì)目標(biāo)layer返回對(duì)應(yīng)的offsetLayer, 目標(biāo)compositing layer再根據(jù)offset合成一個(gè)渲染的紋理buffer
類似Relayout boundary,Paint階段也有Repaint Boundary,目的和layout一樣,就是對(duì)應(yīng)子樹的paint不會(huì)導(dǎo)致外部的repaint,但是Relayout boundary需要開發(fā)人員自己設(shè)置,使用RepaintBoundary widget進(jìn)行設(shè)置,ListView在渲染的item默認(rèn)都是使用了RepaintBoundary,顯而易見ListView的children之間都是相互獨(dú)立的。
Flutter建議復(fù)雜的image渲染使用RepaintBoundary,image的渲染需要io操作,然后解碼,最后渲染,使用RepaintBoundary可以進(jìn)行g(shù)pu的緩存,但是不一定就會(huì)緩存,engine會(huì)判斷這個(gè)image是否足夠復(fù)雜,畢竟gpu緩存還是非常珍貴的,同時(shí)RepaintBoundary還會(huì)對(duì)一些反復(fù)渲染的layer進(jìn)行緩存處理(反復(fù)渲染3次及以上,這個(gè)是flutter的視頻中提到的)
Flutter還處于Beta階段,有些界面編程的接口設(shè)計(jì)還不夠成熟,相比iOS和安卓生態(tài)還很不成熟,需要我們共同的創(chuàng)建,F(xiàn)lutter提供的調(diào)試工具相比一開始接觸的時(shí)候,已經(jīng)完善很多,讓我們給Flutter更多的耐心和包容,期待Flutter越來越完善。
簡(jiǎn)歷投遞:guicai.gxy@alibaba-inc.com
日期:2018-10 瀏覽次數(shù):7274
日期:2018-12 瀏覽次數(shù):4345
日期:2018-07 瀏覽次數(shù):4891
日期:2018-12 瀏覽次數(shù):4187
日期:2018-09 瀏覽次數(shù):5516
日期:2018-12 瀏覽次數(shù):9938
日期:2018-11 瀏覽次數(shù):4823
日期:2018-07 瀏覽次數(shù):4595
日期:2018-05 瀏覽次數(shù):4870
日期:2018-12 瀏覽次數(shù):4337
日期:2018-10 瀏覽次數(shù):5153
日期:2018-12 瀏覽次數(shù):6229
日期:2018-11 瀏覽次數(shù):4482
日期:2018-08 瀏覽次數(shù):4602
日期:2018-11 瀏覽次數(shù):12654
日期:2018-09 瀏覽次數(shù):5595
日期:2018-12 瀏覽次數(shù):4848
日期:2018-10 瀏覽次數(shù):4202
日期:2018-11 瀏覽次數(shù):4541
日期:2018-12 瀏覽次數(shù):6077
日期:2018-06 瀏覽次數(shù):4018
日期:2018-08 瀏覽次數(shù):5452
日期:2018-10 瀏覽次數(shù):4466
日期:2018-12 瀏覽次數(shù):4547
日期:2018-07 瀏覽次數(shù):4372
日期:2018-12 瀏覽次數(shù):4513
日期:2018-06 瀏覽次數(shù):4401
日期:2018-11 瀏覽次數(shù):4387
日期:2018-12 瀏覽次數(shù):4262
日期:2018-12 瀏覽次數(shù):5297
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.