Widget
Why write your own build method
- Some widgets generate renderObjects
- Each Widget generates an Element instance
- The mount method is called when an Element instance is generated
- StatfulWidget, statelessWidget
extents
ComponentElement - ComponentElement: mount -> _firstBuild -> rebuild -> performRebuild -> build
- RenderObjectElement: mount -> _widget.createRenderObject
Component Widget
Generate RenderObject statfulWidget statelessWidgetextentsComponentElement wouldn’t
- Container
- Text
- Hand-written widgets
statfulWidget
If it is a StatefulWidget, a StatefulElement is created
Let’s look at the StatefulElement constructor:
- Call widget createState()
- So StatefulElement has a reference to the created State
- In turn, _state has a reference to the widget
StatefulElement(StatefulWidget widget) : _state = widget.createState(), .... Omit code _state._widget = widget;Copy the code
When we call build, we essentially call the build method in _state:
Widget build() => state.build(this);
Copy the code
Create a process
ComponentElement: mount -> _firstBuild -> rebuild -> performRebuild -> build
The component Widget
Padding
- Create Element: RenderObjectElement
- RenderObjectElement: mount -> _widget.createRenderObject
- Render Widget: Generate the RenderObject
The Widget inheritance chain
Padding -> SingleChildRenderObjectWidget -> RenderObjectWidget -> Widget
Element inheritance
RenderPadding -> RenderShiftedBox -> RenderBox -> RenderObject
Element
A large number of widgets are created and destroyed repeatedly and are unstable, so who keeps the entire application rendering stable? Element! Element is an instance of a Widget and is a detailed location in the tree
Each time a Widget is created, a corresponding Element is created and inserted into the tree.
- Element holds references to widgets;
In SingleChildRenderObjectWidget, we can find the following code:
- In the Widget, an Element is created, and this (Widget) is passed when it is created;
- Element holds applications to widgets;
@override
SingleChildRenderObjectElement createElement() => SingleChildRenderObjectElement(this);
Copy the code
After creating an Element, the Framework calls the mount method to insert the Element at a specific location in the tree:
The mount method
When the mount method is called, the Widget is used to create the RenderObject and the reference to the RenderObject is kept:
- _renderObject = widget.createRenderObject(this);
@override void mount(Element parent, dynamic newSlot) { super.mount(parent, newSlot); _renderObject = widget.createRenderObject(this); assert(() { _debugUpdateRenderObjectOwner(); returntrue; } ()); assert(_slot == newSlot); attachRenderObject(newSlot); _dirty = false; }Copy the code
However, if you look at a Widget of a composite class like Text, it also performs a mount method, but there is no createRenderObject called in the mount method.
- We’ve found that the primary purpose of ComponentElement is to call the _firstBuild method once it’s mounted
@override void mount(Element parent, dynamic newSlot) { super.mount(parent, newSlot); assert(_child == null); assert(_active); _firstBuild(); assert(_child ! = null); } void _firstBuild() { rebuild(); }Copy the code
RenderObject
Create a process summary
The Widget simply describes configuration information:
- This includes the createElement method to create the Element
- CreateRenderObject is also included, but it is not called by itself
Element is an object that actually holds the tree structure:
- Once created, the framework calls the mount method;
- The mount method calls the Widget’s createRenderObject;
- And Element has references to both widgets and RenderObjects;
RenderObject is the object that is actually rendered:
- One of the
markNeedsLayout
performLayout
markNeedsPaint
paint
Methods such as
reference
Flutter widgets – Element – RenderObject