注:rebulild、layout、paint都是在drawFrame過程中完成的
https://juejin.im/post/5b9a7d396fb9a05d3154fa5a


update child Element的時候的child widget,有時候是要this widget的build方法得到的,有時候直接this widget 的 child屬性獲取,不同的widget不一樣

inflateWidget方法的作用就是創(chuàng)建widget對應(yīng)的element
Widget實際上就是Element的配置數(shù)據(jù),Widget樹實際上是一個配置樹,而真正的UI渲染樹是由Element(或者確切說是由RenderObject)構(gòu)成;不過,由于Element是通過Widget生成,所以它們之間有對應(yīng)關(guān)系,所以在大多數(shù)場景,我們可以寬泛地認為Widget樹就是指UI控件樹或UI渲染樹。
一個Widget對象可以對應(yīng)多個Element對象。這很好理解,根據(jù)同一份配置(Widget),可以創(chuàng)建多個實例(Element)。
從創(chuàng)建到渲染的大體流程是:根據(jù)Widget生成Element,然后創(chuàng)建相應(yīng)的RenderObject并關(guān)聯(lián)到Element.renderObject屬性上,最后再通過RenderObject來完成布局排列和繪制。
flutter使用RenderObjects管理傳統(tǒng)UI對象的許多職責(zé)(例如維護布局的狀態(tài))。RenderObjects在幀之間保持不變,flutter的輕量級Widgets告訴框架在狀態(tài)之間改變RenderObjects。
widget和element一一對應(yīng),但是不是所有element都有renderObject。如下代碼所示,如果Element不是 RenderObjectElement,則使用的是子樹中的element的renderObject??衫斫鉃樘峁﹍ayout或paint相關(guān)數(shù)據(jù)的widget/element自身并不代表一塊UI,其是為子控件提供參數(shù)的,所以獲取子樹中的renderObject,通過parentData或者其他方式影響子樹中的renderObject的layout/paint。
//Element class
RenderObject get renderObject {
RenderObject result;
void visit(Element element) {
assert(result == null); // this verifies that there's only one child
if (element is RenderObjectElement)
result = element.renderObject;
else
element.visitChildren(visit);
}
visit(this);
return result;
}
Layer
iOS的每一個UIView都有一個layer,flutter的render object不一定存在layer,一般情況下一個renderObject子樹都渲染在一個layer上,那么什么renderObject具有l(wèi)ayer,子renderObject怎么渲染到這個layer?
- 當(dāng)一個renderObject的 alwaysNeedsCompositing == true 或者isRepaintBoundary == true,renderOject會有對應(yīng)的compositing layer
- 子renderObject會對目標layer返回對應(yīng)的offsetLayer, 目標compositing layer再根據(jù)offset合成一個渲染的紋理buffer
flutter框架的四層封裝

- dart:ui是最后一個Dart層,它基本上處理與Flutter引擎的通信。
- 大多數(shù)時候你會發(fā)現(xiàn)Flutter使用的是一個
RenderBox而不是RenderObject,RenderObject中沒有坐標系統(tǒng)。這是因為項目背后的人們意識到一個簡單的盒子布局協(xié)議非常適合構(gòu)建高性能的UI。想想放在它自己的盒子里的每個小部件,這個盒子被計算出來,然后與其他預(yù)先布置好的盒子一起排列。因此,如果布局中只有一個窗口小部件發(fā)生更改(例如按鈕或開關(guān)),則系統(tǒng)只需要重新計算這個相對較小的盒子。 - element持有對Widget和RenderObject.RenderObject負責(zé)布局,繪畫和交互處理,實例化非常昂貴。element是不可變Widget樹和可變RenderObject樹之間的粘合劑。Elements主要是對象,它們非常擅長將兩個對象相互比較
State的生命周期
- initState
- didChangeDependencies
- didUpdateWidget
- build
- deactivate
- dispose

剛進入頁面
- initState
- didChangeDependencies
- build
退出頁面
- deactivate
- dispose
deactivate
# StatefulElement
@override
void deactivate() {
_state.deactivate();
super.deactivate();
}
# Element
void deactivateChild(Element child) {
...
owner._inactiveElements.add(child); // this eventually calls child.deactivate()
...
# BuildOwner
final _InactiveElements _inactiveElements = _InactiveElements();
void add(Element element) {
...
if (element._active)
_deactivateRecursively(element);
...
}
static void _deactivateRecursively(Element element) {
...
element.deactivate();
...
}
flutter熱重載
flutter熱重載會執(zhí)行reassemble方法,主要流程如下
