Widget是我们在Flutter中接触到的最多的类。
从逻辑上来说,Widget的关系图可以分为以下几个部分。(当然Flutter中并没有组合型组件这么一个Class)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
@immutable abstract class Widget extends DiagnosticableTree { const Widget({ this.key }); final Key? key; ... @protected Element createElement(); ... static bool canUpdate(Widget oldWidget, Widget newWidget) { return oldWidget.runtimeType == newWidget.runtimeType && oldWidget.key == newWidget.key; } }
|
Widget的源码非常简单,这里把主要的贴出来。可以看到Widget类中主要的东西有
1.构造方法中入参key
2.静态的canUpdate方法
3.抽象方法createElement()
而在Widget的子类中,都各自对createElement()进行了具体的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| abstract class StatelessWidget extends Widget { ... @override StatelessElement createElement() => StatelessElement(this); ... @protected Widget build(BuildContext context); }
abstract class StatefulWidget extends Widget { ... @override StatefulElement createElement() => StatefulElement(this); ...
@protected @factory State createState(); }
abstract class ProxyWidget extends Widget { const ProxyWidget({ Key? key, required this.child }) : super(key: key);
final Widget child; }
abstract class InheritedWidget extends ProxyWidget { ... @override InheritedElement createElement() => InheritedElement(this); ... }
abstract class ParentDataWidget<T extends ParentData>extends ProxyWidget{
@override ParentDataElement<T>createElement()=> ParentDataElement<T>(this);
@protected void applyParentData(RenderObject renderObject); }
|
1 2
| StatelessElement,StatefulElement, InheritedElement,ParentDataElement,都是ComponentElement的子类
|
可以看到组合类型的Widget的createElement()方法创建了不同类型的ComponentElement
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| RenderObjectWidget系列的createElement()方法都是创建了RenderObjectElement
abstract class RenderObjectWidget extends Widget {
@override @factory RenderObjectElement createElement();
@protected @factory RenderObject createRenderObject(BuildContext context);
@protected void updateRenderObject(BuildContext context, covariant RenderObject renderObject) { }
@protected void didUnmountRenderObject(covariant RenderObject renderObject) { }
}
abstract class LeafRenderObjectWidget extends RenderObjectWidget { @override LeafRenderObjectElement createElement() => LeafRenderObjectElement(this); }
abstract class SingleChildRenderObjectWidget extends RenderObjectWidget { final Widget? child;
@override SingleChildRenderObjectElement createElement() => SingleChildRenderObjectElement(this); }
abstract class MultiChildRenderObjectWidget extends RenderObjectWidget {
final List<Widget> children;
@override MultiChildRenderObjectElement createElement() => MultiChildRenderObjectElement(this); }
|
1 2
| LeafRenderObjectElement,SingleChildRenderObjectElement, MultiChildRenderObjectElement都是RenderObjectElement的子类。
|
RenderObjectWidget的createElement方法创建了不同类型的RenderObjectElement。RenderObjectWidget提供createRenderObject方法创建RenderObject。
总结
Widget是描述 [Element] 的配置文件,主要功能就是createElement(),该方法都是返回了xxxElement(this),可以看到创建Element的入参是Widget。
RenderObjectWidget还提供createRenderObject(BuildContext context)方法创建RenderObject。
单独看Widget的源码其实没什么意义,需要结合Element的源码才行。