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, statelessWidgetextentsComponentElement
  • 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 themarkNeedsLayout performLayout markNeedsPaint paintMethods such as

reference

Flutter widgets – Element – RenderObject