1. 程式人生 > 實用技巧 >Flutter 詳解(七、深入瞭解繪製原理)

Flutter 詳解(七、深入瞭解繪製原理)

Widget

flutter中,every is widget,理解起來很容易,我們所使用的顯示文字的Text,展示圖片的Image,展示位置資訊的Padding,都是Widget.

在閱讀Flutter原始碼的,你可能會注意到Widget的定義:

@immutable
abstract class Widget extends DiagnosticableTree {
  ...
  const Widget({ this.key });
  final Key key;
  static bool canUpdate(Widget oldWidget, Widget newWidget) {
  return oldWidget.runtimeType == newWidget.runtimeType
      && oldWidget.key == newWidget.key;
}
  ...
}

官方這樣講:

A widget is an immutable description of part of a user interface.

小部件是對使用者介面的不可變的描述。

我們注意到左上角有@immutable,這個很重要,視窗小部件中的所有屬性都必須為final,一旦例項化,就無法跟更改內部屬性,但是事實上,我們的UI不可能一成不變的,因此Flutter如何管理UI的狀態呢?

Flutter有三棵樹,Widget樹、Element樹、RenderObjects樹,這些樹分工不同,將他們組合在一起,來優化UI的各種可能性。

Element是什麼

記錄一個Widget的位置資訊

An instantiation of a [Widget] at a particular location in the tree.

它是樹的可變部分,用於管理UI更新和更改,您可以將它看做是管理widget的生命週期的元素。每個元素都引用了一個widget,很簡單的。

RenderObject是什麼

Flutter繪製UI時,它不會檢視Widget的樹,而是檢視RenderObjects,它控制大小,佈局並保留用於繪製實際widget的所有邏輯,這就是渲染物件例項化很好效能的原因。

為了更好的展示這三棵樹,我們看下面小部件:

class HomeRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('Hello world'),
    );
  }
}

當我們啟動應用時

1.Flutter 將遍歷您的視窗小部件並建立視窗小部件樹。
2. 與小部件對應,Flutter建立元素樹,在其中通過createElement()建立每一個Element物件。
3. 當Element呼叫createRenderObject()時,將建立每個渲染物件。

如圖所示:

當我們要改變小部件Text的值,我們看下Flutter Inspector的資訊。

更改前:

更改後:

text中顯示的值從4變為5,它的renderObject並未改變。

因為在例項化渲染物件很耗費效能,flutter在這點做了保留,省掉了重複例項化的開銷,如果他們具有相同的型別,則無需重新建立渲染物件。我們只需要更新key的值,可以做到重新建立渲染物件。

在實際開發中,一個頁面估計至少幾十個widget,或者上百個widget,那麼對應的elementrenderObject也是數量相等的,因此重新建立整個樹是非常消耗效能的,flutter最大程度減小效能浪費,從而獲得更佳的UI效能。

參考

文章彙總

<<Dart 非同步與多執行緒>>

<<Flutter 詳解(一、深入瞭解狀態管理--ScopeModel)>>

<<Flutter 詳解(二、深入瞭解狀態管理--Redux)>>

<<Flutter 詳解(三、深入瞭解狀態管理--Provider)>>

<<Flutter 詳解(四、深入瞭解狀態管理--BLoC)>>

<<Flutter 詳解 (五、深入瞭解--Key)>>

<<Flutter 詳解 (六、深入瞭解--Stream>>

<<Flutter 詳解(七、深入瞭解繪製原理>>