定义

Widget:存放渲染内容、它只是一个配置数据结构,创建是非常轻量的,在页面刷新的过程中随时会重建。

其中Widget根据功能可以分为三类:

  • 组合类StatelessWidget/StatefulWidget:比如我们常见的Container就是一个组合类的控件,它主要负责组合封装多个其他负责绘制的原子组件。
  • 代理类inheritedwidget:它的父类是ProxyWidget,顾名思义。简单来说,InheritedWidget 的作用是向它的子 Widget 有效地传播和分享数据,当 InheritedWidget 作为一个Parent Widget时,它下面的Widget tree的所有Widget都可以去和 InheritedWidget 发生数据传递和交互。当数据发生改变时,一部分控件需要 rebuild,另外的控件不需要 rebuild 的时候,可以使用 InheritedWidget
  • 绘制类RenderObjectWidgetRenderObjectWidget会负责创建出负责实际渲染的RenderObject对象,RenderObject负责实际的layout()paint()。后期有空,我会手动写一个RenderObject

Element: 是分离 WidgetTree 和真正的渲染对象的中间层,可以看成flutter的骨架。 Widget 用来描述对应的Element 属性,同时持有WidgetRenderObject,存放上下文信息,通过它来遍历视图树,支撑UI结构。

其中Element可以根据功能分成两大类:

  • 组合类ComponentElement:主要包括如下 StatelessElement / StatefulElement / ProxyElement 子类;其中各Element都是与 Widget 对应的。
  • 绘制类RenderObjectElementRenderObjectElement对应的是RenderObjectWidget

RenderObject用于应用界面的布局和绘制,负责真正的渲染,保存了元素的大小,布局等信息。

当应用启动时 Flutter 会遍历并创建所有的 Widget 形成 Widget树,通过调用 Widget 上的 createElement() 方法创建每个 Element 对象,形成 Element 树。最后调用 ElementcreateRenderObject() 方法创建每个渲染对象,形成一个 RenderObject 树。

Widget => Element

如何通过Widget更新Element:

  • Element/ComponentElement: 单个Element时候通过updateChild方法更新;
E } l e i } f i } } r m / f i f e e i r n i } } } e n t n ( f e a ( / f l e u t n n d t l c i n e i c n e d n s o w r ? e e ( e u h ( f e l / f h e l / e e e l C n w w c a r E i w c u w s u i w s a w d h u W W h c n l l i h ( p C e ( p l C e c C { i n p i i i t e d d i c d h u c d d h t h c l e d d d l i n m g l h a i i p h a . i { i i h d w a g g d v u e ! e d i t l f d i t u l v l i C t e e a l n = t . l e d a l e p d a d l = h e t t ! t l t w d S ( t d S d t d i C = e ; n i . l = W e . l a = e = i l h n = C n u d s o i s o t C n n d i u = n h e l g l t c d l t e c h i u f ; l l u i w l e o F h g o F ( h i n l l d l n l l C ) t t o i e t o n i l f l a ( u l d h r l t r e l i d l t E l ) ( i { = ! C d . ! C w d n ( a e l l c l = = h ; c = h W ; f c t W e o ) h d i a r i i l h e i m l i ; n n l n u n l d a i W d e d { l e e d U n e d g t l i i g n d w w ( p t w ( e e d d n e t c ) W S c d i S c t W ) g f t ? h ; i l h a m l h ) i ; e l ( i d o i t e o i ; d t a n c l g t l e t t l g ( t e h d e ) d ( y ) d e n e w i t , c p , t e W l n ) h e w i d u n i n W w d , l { e l k e w i i g l w d e w i d d e W S . y S d g g t i l w l g e e , d o i o e t t g d t d t t , n e e ) g ) e t a ; e ; n w ? c t e S t , w e l n i e S l o e v n l l e t w a e e o m ) W t w m t e ; i e W e ) n d C i n ; t g h d t e i g t l e , d t ) O ) b j { e c t ? n e w S l o t ) {

大致归纳一下,如下表:

标题 newWidget == null newWidget != null
child == null Returns null. Returns new [Element].
child != null Old child is removed, returns null. Old child updated if possible, returns child or new [Element].
  • RenderObjectElement: 多个Element时候通过updateChildren方法更新;
L i / / / s / / / } t < E } i i i i f E w } w } f M i } w } n o w } i } r E f l n n n n i l h h i a f h e l h f e l o e r t t t t n e i f f i f n p n o i f f a i o n n p o w } W i E f i } f n p n w d i f f f n p n o f } t e r m e a m l i i f i e r e l l i i s f l e a < ( l h i l l i f i e r e C C l i i i e r e l ( o u m g e t n o n o l o e e n n b n w e w d e n n s b d w l K h d i f i } o d e e n f i } n w e w h h e n n n w e w d h r i r e o n u e l e l l n a a r a C v C C a a e r C C E e a K l i f l g m a ( i f a C v C i i a a a C v C C a f n n t t r w d w d L d t l l o e l h i h h l l r o e h h l b y v e e n i e d e ( e l h n o i } l h i h l l l l l h i h h v ( d t t ? n C C C C i C ? l a i o i i t l a i i e o , e y a f l C t n n a a ( l f i o i d d i o i i E e f ( e n > e h h h h s h o E W d k E l u l l o E W ( d k l l m o O e l o o s d h e t W v l k d i } } E l u l r r E o E W E l u l l l O i f a e n r f i i i i t i p l l i C ; l d s d d l l i o C ; d d e l E l d o l l e e i K w ? i e e C f l d s d e e l l l i l d s d d e l n o c w u C e o l l l l < l r d e d h e r C r r d e d l h r r n l d C l E d o d a l e C d O K y h o e e r C r n n e d e d e r C r r m d a r t C p h p r d d d d E d e C m g i m e h e e C m g d i e e t h e C h d l C l K c d y h o g l e i l ( l l l m e h e B B m C m g m e h e e e C l g i h d i l g r r r r l r v h e e l e n i n n E h e e C l n n a m h i C e h d e t r i l e d y ! l d W d s d e n i n o o e h e e e n i n n n h o v i a l a o e e e e e e i E i n t d n [ l T T l i n t h d B B v e i l h m i C y i e l d t C ? = d C i w r K e N C n [ l T t t n i n t n [ l T T t i E t a l t d c t n n n n m n o l l t t n d o o e l t i o o e n l d i e l h e v n o d C h h d e e e o h t n d o t t t l t t n d o o l l t t d e r e t T T B B e u e d ? n = e p p m d ? n l = t t O t d r l n d i d a T l r h n i k n = i g m y { t i e p o o d n e p p d e e e r C e W e o o o o n : s m r e = n w = e r e d = t t l > r e d t l C t o d e i e l e u l e f o e l n w = m m r o e n w = r m n C e h n i n p p t t t C e e o w e C + + n e o w o o d ? e n r ? ! d h e p K n l w d y l o d t o v d a d e C + e l w e C + + e e C h n i t C t t > L h n n l W n w h n = = t n l W = n m m C n e = . i C e T d W r l l . u e C w h n = = = n d W w h n = = n n h i ; l h h = = o o i i t T d i u C i e T d i = u h o ) = n o w l h + y o ; i e = ) d ! c n h m = C i e T C i C i e t i l d N i m m n s l o C d l h l w 1 1 o C d l - - E i l T l n i d i = C p d n K = a d i i a h l w 1 n o o h d h l w 1 1 & l d r u l 0 0 e t d p h g l i d C ; ; p h g n l = = l l d { < o d u d r l h g ) n { e n t l t n i d C ; e l p i g i d C ; ; & o d ( e c l d ; ; = = w < ; i e l r h i e u e d K K p C l g e d 1 i < e e y n U a d c u l r h w d l e l r h l r o n h l r C E < l t d e i < l t l 1 1 m r e e h l e n ( ; l = t { w e u p f r h l d e i W C < d t d e i E o d e l ( i I e n o h l = d n l = d l ; ; e e y y < i ) t [ o d W d l d m r e , l n l i h = n l l l C n d L l f n e l i e = = T d = n n e , = l . o l r n = i C l a a o n ; = T d d i = = = T d e d h C i d F w d l m o = ! o ; o = ! t d d { k l d e e d h ) t t m . l o ; g l o o ; m K i = h s o ! W C d e l n W u p l n W = C E o e d C n w n g i e c r e u p e d l o n u p e e l = i t r = i h r n d r e i p ] d r e i h l l = y C h C e e l { ( h o e t p ] t r d l e p ] n y d l < g d i e t C e w d d C e w o d o i e d h i h w t d o ! l m ' d s e C d w d t e n d E o n g l n > h p W g a = h p W l g W l l m C r ! i l E i W . r l d o s a = . n h C W a = d i u ) l t u e d . i l i e t i l i d e i d d e h e = l d l l i k e d K v t l . i h i t C n l ; e t l t r = f l a d t e n l a d C t d C r n i p d ) e d d e n C e e p e n e l l i d e n h l m e l s e i d c g . C e d c g h . g h e t l l n . ; m r g y ! h y ( r C e n e d l g C e i o e o n . n o l r e e c h w r e e i c e i n > d a u w e e e ; [ i e k e h w g n r d e h w l l n l ( & l . l l e W t a i C e W t l a t l ; { r c l i n n t k l d e t i C t g e r t i C d d t d E & e l d e n i s n l h n i s d n d } e e l d t B s e d C y e l h h t n e s l h r K > C l n e C d B t [ U d i B t [ . U K r ; n W ) g o [ y . h ) n d i h B n [ d i e e ! h e f g n h ( o h n p ( l o h n _ p e e B i e t n ] w i ; d ( l - o [ n ( l n y f o i m o t g i n t N e d o d t N e l d y n o t t t e ; i l o d - t o e o d ! e o l l e r h t l e t u w a l ; t u w i a T t h . o w d d w l ; 1 t l w l ; . d r d d n g h d w o l C t d o l C f t E o t N k m C g r e d ; 1 o d C d i C g C t o - r W m l h e C m l h e e l p o u e ) h e e C ; m C h C s h o h t - e i ) I i ( h ) I i c ( e m l y i t n d h ) h i h N i t i c t 1 n d f l o i f l y o m < ) l ! { l , i i i l i o l t l h e ; 1 . g & F d l l & F d c l e = I ] d s d l & l d l t d e d n i n ; l e & o r d d & o r l d n { f r n o n d & d r d E r n r u l C e t r e C , r e e C t o F = e e ' , r e , m e C e l d h n s ( g n h ( g n S h l o n w w t ( e n p n h n l ) i g . n o T i n n o B t i o d r o T W e n n n T n t . i , l t l e t o l e e t o a l l C g l o i s e e T o e y v l { d h e w t p d w w t t t d d h o d p d d e w w o p w ) a d L r n C e ] . W C e t e . K i t C ] g o e W C p ] W l r i e = g h n ; w i h n o w e l t h ; e n i h ] ; i { u e s n = t i ( i d i ( m = i y d e i t ' i d i ; d e n t . h l o d g l o ] = d C r n l ) t t g l g s . < c n , d l g e d l ; g h e ( d ) e d e ) c W o e r d e t r d _ e i n o ; u f t r t o i n w _ e C t , e C E t l B l { n o , e , { n d t W N n h , n h l , d o d s r n t g a i u T i I T i e r t C y I T I a e i d l o l n n o l m n e t h n n n o n i t n g l p d e d p d e e n o i c o d p d n > s e E r w e r n w m l w e e s ( t l < e W x < e t W ; d i . x < x ( n c s e = n i e = n L i r t e = e o e h . m [ d d [ i d e d d l w i l e n o g S n o f g n l S n S d W l e n e l e l e l e e [ a l e l C i d n t w d t o w d c t o t o w o h d ) g . C C ) t C C y ) l e t C t i g t i h h ) < h h c ) d r < h < l e ? h n i i E i i l C E i E d t s l l l l l e h l l l ) s n ? t d d e d d . i e d e ) , u a r r m r r a l m r m l n e e e e e c d e e e { l c n n n n n t r n n n e B T t B B i e t B t S : , o o ? o o v n ? o ? e t p > t t e T > t > t c g t ] ( t t ) o ( t ( < h r o ) n o o ; p n o n E i o m ; e m m ] e m e l l w ) w ) ] ) w ) w e d a ) C ) ) ; C ) C m ; b h ; h h e l { i { i { i n e l l l t : d d d > r r r ? f e e e a n n n f l T T T o s o o o r e p p p g ) , , , o ; t p p p t r r r e e e e n v v v C i i i h o o o i u u u l s s s d C C C r h h h e i i i n l l l d d d } ) ) ) ) ) ) ) ! ! ! { ; ; ;

该函数的主要职责如下:

  • 复用能复用的子节点,并调用updateChild对子节点进行更新。
  • 对不能更新的子节点,调用deactivateChild对该子节点进行失效。

我们注意到updateChild如果old child是空或者无法update就需要inflateWidget; 我们从源码看看创建方法inflateWidget():

E } l e f i } f n r m i f / i / e / e e n f i } n w t n a ( i f a c C u t l k n n f r l h h c r e a ( e i e E i i h n i K y l n w n t l E l l i n e e C a u e l d d l n f y i E w h l r m e . d e l ? s l C i n e m m w a e h l E n e o e C t k G m i d l u t n u l h e e l e l . e p t n e i W y o n d _ m d e t m l i b t a e a n l ( e d d = a ? ! c n t e e t n ; g l = t t e w m h t e n K n i ? d C e i t e e e n v C h n s ( w y w u a u h i t , W W ) C l t p i l i i h l e d l d n d d { i ) W a d e g g l i t ! = w e e d { t e ; S t t h d n l . = P C e o n k a h w t e e _ r i W ) w y r e l i ; W ; e n d d i t t g d a ( = e g k t t e e h u . t I i p c , n s d r a , a e O c t a b t n e t j i e C e e v w h E c e S i l t E l l e ? l o d m e t ( e n m ) n n e e ; e t w n w ( S t C ) l ( h ; o k i t e l ) y d , , { n n e e w w W W i i d d g g e e t t ) , ; n e w S l o t ) ;

逻辑非常简单,创建一个element,然后mount到当前element

RenderObject

RenderObjectWidget会调用createElement,创建出RenderObjectElement, 然后RenderObjectWidget会调用createRenderObject,创建出RenderObject, 然后通过[RenderObjectElement.mount]方法,将RenderObject挂载为RenderObjectElement._renderObject属性。从此可以看出,Element是连接WidgetRenderObject的桥梁。