您好,登錄后才能下訂單哦!
這篇文章主要介紹了Flutter渲染原理是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Flutter渲染原理是什么文章都會有所收獲,下面我們一起來看看吧。
在Flutter 中,萬物皆是Widget,無論是可見的還是功能型的。一切都是Widget.
官方文檔中說的Widget 使用配置和狀態來描述View 界面應該長什么樣子。
它不僅可以表示UI元素,也可以表示一些功能性的組件如:用于手勢檢測的 GestureDetector、用于APP主題數據傳遞的Theme、布局元素等等
兩個重要的方法
一個是通過 createElement 來創建 Element 對象的,
一個是根據 key 來決定更新行為的 canUpdate 方法。
在這個方法中會對比runtimeType (也就是widget 的類型)和 key 是否相同
@immutable abstract class Widget extends DiagnosticableTree { /// Initializes [key] for subclasses. const Widget({this.key}); final Key? key; @protected @factory Element createElement(); /// A short, textual description of this widget. @override String toStringShort() { final String type = objectRuntimeType(this, 'Widget'); return key == null ? type : '$type-$key'; } @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense; } @override @nonVirtual bool operator ==(Object other) => super == other; @override @nonVirtual int get hashCode => super.hashCode; static bool canUpdate(Widget oldWidget, Widget newWidget) { return oldWidget.runtimeType == newWidget.runtimeType && oldWidget.key == newWidget.key; } // Return a numeric encoding of the specific `Widget` concrete subtype. // This is used in `Element.updateChild` to determine if a hot reload modified the // superclass of a mounted element's configuration. The encoding of each `Widget` // must match the corresponding `Element` encoding in `Element._debugConcreteSubtype`. static int _debugConcreteSubtype(Widget widget) { return widget is StatefulWidget ? 1 : widget is StatelessWidget ? 2 : 0; } }
Element 就是一個Widget 的實例,在樹中詳細的位置。
An instantiation of a Widget at a particular location in the tree
渲染樹上的一個對象。負責具體布局和繪制這些事情。
從創建到渲染的流程 :
根據Widget 生成Element,然后創建響應的RenderObject并且關聯到Element.renderObject 屬性。最后再通過RenderObject 來完成布局和繪制。
依賴關系:
Element 樹根據Widget 樹生成,而渲染樹又依賴于widget 樹。
widget 和 element 是一一對應的嗎 ? 為什么 ?
答:是一一對應的。
因為 abstract class Widget ,本身是一個抽象類,這個抽象類中有一個抽象方法叫做createElement(),子類必須實現這個抽象方法,所以是一一對應的。
widget 和 renderObject 是一一對應的嗎 ? 為什么 ?
答:不是的
因為只有這個widget 繼承自RenderObjectWidget 的時候,才會有對應的renderObject
像類似 Padding , Row,SizedBox,Center 這種組件繼承自RenderObjectWidget的組件會有一一對應的關系
//class Padding extends SingleChildRenderObjectWidget // Padding(); // class Flex extends MultiChildRenderObjectWidget // Row()
BuildContext 是什么 ?
答:是Element,不管是StatefulWidget 還是StatelessWidget 都會重寫父類的build 方法,
build 方法傳入的一個參數叫做BuildContext, 我們拿StatelessWidget來說,其本身創建一個StatelessElement,而在這個Element內部重寫StatelessElement父類的build方法,而在這個build方法內部會調用_widget.build 方法,并且把this傳遞進去。那么這個this 就是element 。
/// An [Element] that uses a [StatelessWidget] as its configuration. class StatelessElement extends ComponentElement { /// Creates an element that uses the given widget as its configuration. StatelessElement(StatelessWidget super.widget); @override Widget build() => (widget as StatelessWidget).build(this); @override void update(StatelessWidget newWidget) { super.update(newWidget); assert(widget == newWidget); _dirty = true; rebuild(); } }
Widget 頻繁更改創建是否會影響性能?復用和更新機制是什么樣的?
不會影響性能,因為只是一些配置信息,沒有有布局渲染到頁面上去。中間層Element 會通過widget 的runtimeType 和 Key 來對比是否進行更新操作。
Build 方法會在什么時候調用 ?
Element 創建完畢之后會調用mount 方法,對于非渲染的ComponentElement 來說,mount主要執行的是Widget 中的build 方法。在StatelessElement 中直接使用的是 widget.build(this),
而在StatefullWidget 方法中,通過的是state.build(this)。在StatefulElement 這個類中,
初始化列表的給state 進行了賦值操作。通過widget調用createState方法之后,把state賦值給自己的_state 屬性。
StatefulElement(StatefulWidget widget)
: _state = widget.createState(),
createState 方法什么時候調用?
答:創建Element 的時候。
Flutter 會在遍歷 Widget 樹時調用 Widget 里面的 createElement 方法去生成對應節點的 Element 對象,同時執行 StatefulWidget 里面的 createState 方法創建 state,并且賦值給 Element 里的 _state 屬性,當前 widget 也同時賦值給了 state 里的_widget,state 里面有個 widget 的get 方法可以獲取到 _widget 對象。
關于“Flutter渲染原理是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Flutter渲染原理是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。