最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flutter渲染原理深入解析

 更新時(shí)間:2023年04月13日 09:45:48   作者:iOS_Apple  
眾所周知?Flutter是由Google推出的開(kāi)源的高性能跨平臺(tái)框架,一個(gè)2D渲染引擎。在Flutter中,Widget是Flutter用戶(hù)界面的基本構(gòu)成單元,可以說(shuō)一切皆Widget。下面來(lái)看下Flutter框架的整體結(jié)構(gòu)組成

Widget Element RenderObject之間的關(guān)系

1 Widget

在Flutter 中,萬(wàn)物皆是Widget,無(wú)論是可見(jiàn)的還是功能型的。一切都是Widget.

官方文檔中說(shuō)的Widget 使用配置和狀態(tài)來(lái)描述View 界面應(yīng)該長(zhǎng)什么樣子。

它不僅可以表示UI元素,也可以表示一些功能性的組件如:用于手勢(shì)檢測(cè)的 GestureDetector、用于APP主題數(shù)據(jù)傳遞的Theme、布局元素等等

兩個(gè)重要的方法

一個(gè)是通過(guò) createElement 來(lái)創(chuàng)建 Element 對(duì)象的,

一個(gè)是根據(jù) key 來(lái)決定更新行為的 canUpdate 方法。

在這個(gè)方法中會(huì)對(duì)比runtimeType (也就是widget 的類(lèi)型)和 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;
  }
}

2 Element

Element 就是一個(gè)Widget 的實(shí)例,在樹(shù)中詳細(xì)的位置。

An instantiation of a Widget at a particular location in the tree

3 RenderObject

渲染樹(shù)上的一個(gè)對(duì)象。負(fù)責(zé)具體布局和繪制這些事情。

4 結(jié)合圖說(shuō)一下其三者的關(guān)系

從創(chuàng)建到渲染的流程 :

根據(jù)Widget 生成Element,然后創(chuàng)建響應(yīng)的RenderObject并且關(guān)聯(lián)到Element.renderObject 屬性。最后再通過(guò)RenderObject 來(lái)完成布局和繪制。

依賴(lài)關(guān)系:

Element 樹(shù)根據(jù)Widget 樹(shù)生成,而渲染樹(shù)又依賴(lài)于widget 樹(shù)。

5 一些小問(wèn)題

widget 和 element 是一一對(duì)應(yīng)的嗎 ? 為什么 ?

答:是一一對(duì)應(yīng)的。

因?yàn)?abstract class Widget ,本身是一個(gè)抽象類(lèi),這個(gè)抽象類(lèi)中有一個(gè)抽象方法叫做createElement(),子類(lèi)必須實(shí)現(xiàn)這個(gè)抽象方法,所以是一一對(duì)應(yīng)的。

widget 和 renderObject 是一一對(duì)應(yīng)的嗎 ? 為什么 ?

答:不是的

因?yàn)橹挥羞@個(gè)widget 繼承自RenderObjectWidget 的時(shí)候,才會(huì)有對(duì)應(yīng)的renderObject

像類(lèi)似 Padding , Row,SizedBox,Center 這種組件繼承自RenderObjectWidget的組件會(huì)有一一對(duì)應(yīng)的關(guān)系

//class Padding extends SingleChildRenderObjectWidget
// Padding();
// class Flex extends MultiChildRenderObjectWidget
// Row()

BuildContext 是什么 ?

答:是Element,不管是StatefulWidget 還是StatelessWidget 都會(huì)重寫(xiě)父類(lèi)的build 方法,

build 方法傳入的一個(gè)參數(shù)叫做BuildContext, 我們拿StatelessWidget來(lái)說(shuō),其本身創(chuàng)建一個(gè)StatelessElement,而在這個(gè)Element內(nèi)部重寫(xiě)StatelessElement父類(lèi)的build方法,而在這個(gè)build方法內(nèi)部會(huì)調(diào)用_widget.build 方法,并且把this傳遞進(jìn)去。那么這個(gè)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 頻繁更改創(chuàng)建是否會(huì)影響性能?復(fù)用和更新機(jī)制是什么樣的?

不會(huì)影響性能,因?yàn)橹皇且恍┡渲眯畔?,沒(méi)有有布局渲染到頁(yè)面上去。中間層Element 會(huì)通過(guò)widget 的runtimeType 和 Key 來(lái)對(duì)比是否進(jìn)行更新操作。

Build 方法會(huì)在什么時(shí)候調(diào)用 ?

Element 創(chuàng)建完畢之后會(huì)調(diào)用mount 方法,對(duì)于非渲染的ComponentElement 來(lái)說(shuō),mount主要執(zhí)行的是Widget 中的build 方法。在StatelessElement 中直接使用的是 widget.build(this),

而在StatefullWidget 方法中,通過(guò)的是state.build(this)。在StatefulElement 這個(gè)類(lèi)中,

初始化列表的給state 進(jìn)行了賦值操作。通過(guò)widget調(diào)用createState方法之后,把state賦值給自己的_state 屬性。

StatefulElement(StatefulWidget widget)

: _state = widget.createState(),

createState 方法什么時(shí)候調(diào)用?

答:創(chuàng)建Element 的時(shí)候。

Flutter 會(huì)在遍歷 Widget 樹(shù)時(shí)調(diào)用 Widget 里面的 createElement 方法去生成對(duì)應(yīng)節(jié)點(diǎn)的 Element 對(duì)象,同時(shí)執(zhí)行 StatefulWidget 里面的 createState 方法創(chuàng)建 state,并且賦值給 Element 里的 _state 屬性,當(dāng)前 widget 也同時(shí)賦值給了 state 里的_widget,state 里面有個(gè) widget 的get 方法可以獲取到 _widget 對(duì)象。

到此這篇關(guān)于Flutter渲染原理深入解析的文章就介紹到這了,更多相關(guān)Flutter渲染原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

最新評(píng)論

宣城市| 墨玉县| 琼中| 衡阳市| 屏边| 丹阳市| 历史| 竹山县| 祁东县| 灵寿县| 紫阳县| 巴中市| 安义县| 新丰县| 宣城市| 香格里拉县| 旺苍县| 封丘县| 化隆| 临颍县| 嘉荫县| 宁化县| 通山县| 梓潼县| 乳源| 河间市| 庆安县| 吉林省| 广昌县| 清丰县| 迁安市| 资阳市| 亳州市| 景洪市| 甘谷县| 广水市| 满城县| 绿春县| 阜新市| 武宣县| 晋城|