Article From:

  Preface: a word in the official document of Flutter: you build your UI out of widgets (using Flutter to develop UI interfaces, using Widget), however, Widget is not what we really seeWhat’s behind the back of the view? In fact, Flutter Framework provides three view trees, that is, Widget Element RenderObject, but when we use Flutter development interfaces, we usually only use widGet deals with the Materail style shown in the previous article or the various Widget of the Cupertino (IOS style), but Flutter interface development is a responsive programming, and Widget is immutable, then,Who will deal with the problems of real rendering, refresh and layout? This article is going to find out what other basic classes support Widget’s fast lightweight rendering besides Widget.


Look at the definition and description of Widget: Describes the configuration for an Element. (providing configuration information for Element), from this sentence to Widget and EleMent is closely related, and gives Element some information, is it the relationship between the boss and employees? The boss sends instructions to employees, and the specific things are done by employees. Let’s try to extract some details from official documents. First, let’s see what Widget is.
Let’s first look at what attributes are included in the Widget class.
 1:KEY key
 2:int hasCode
 3:TYPE runtimeType
WidgetIt is part of the user interface and is immutable (immutable). Widget will be inflate to Element, and Element will manage the underlying rendering tree.WidgetThere is no variable state itself (all fields must be final). If you want to associate the mutable state with Widget, you can use StatefulWidget and StatefulWidget by using StatefulWidget.cre.The ateState method creates State objects and extends them to Element and merges them into trees.


Therefore, Widget does not directly manage the state and rendering, but manages the state through the State object. The next article will mainly talk about the object of State.


A given Widget can be included in a tree (zero or multiple times). A given Widget can be placed multiple times in a tree, for example, multiple TextWidget. Every time you put a Widget in a tree, it will be expanded to a Element.Widget, flavored many times into the tree, will be expanded to the corresponding element multiple times.


  For example, in real interface development, a UI view tree may contain multiple TextWidget (Widget may be used many times), but these are called TextWidget’s widget and are filled (inflate) into an independent ElemIn ENT;


WidgetThe property of Key controls how a Widget can replace another Widget in the tree. If the runtimeType and key attributes of the two Widget are equal (= =), the new widget is updated by Element (that is, by using the new W).Idget calls Element.update) to replace the old Widget. Otherwise, if the runtimeType and key attributes of the two Widget are not equal, the old Element will be removed from the tree, and the new Widget will be expanded toIn a new Element, this new Element will be inserted into the tree.

 This is mainly involved in the update and removal of Widget, insert and other operations, before the operation of this operation, the two attributes of Widget: runtimeType and key are used for comparison judgment;


FlutterThe visible tree to create Element is variable than Widget. In common Flutter interface development, we do not operate Element directly, but implement internal logic from the framework layer; as in a UI view tree, there may be multiple TextWiDget (Widget is used many times), but placed inside the view of the internal view tree, these TextWidget are filled into separate Element.

Similarly, let’s look at the attributes in Element class first.

Element propertyform
depthintThe depth of the tree root Element must be greater than 0
int get depth => _depth;
dirtyboolIf Element has been marked for reconstruction, return to true
bool get dirty => _dirty;
@overrideint get hashCode => _cachedHash;
ownerBuildOwnerManaging the Element lifecycle
@overrideBuildOwner get owner => _owner;
renderObjectRenderObjectIf the object is RenderObjectElement, the rendering object is the object at this location in the tree. Otherwise, the getter will go down the tree until you find a RenderObjectElement. 
sizeSize ellipsis ellipsis
slot  ellipsis ellipsis
widgetWidgetThe configuration information of this Element
@overrideWidget get widget => _widget;
You can see renderObject and widget from the properties of Element, indicating that Element holds instances of these two classes.
Let’s take a look at the introduction of Element in the document: An instantiation of a Widget Widget at a particular location in locationAn example of the fixed position Widget;
Here is a further description of the relationship between Widget and Element: Element is an instance of Widget, that is, Element is a truly working employee, executing the boss’s strategic deployment; and we go on to look at the description in the document:
WidgetDescribes how to configure subtrees, but because Widget is immutable (immutable), you can use the same Widget to configure multiple sub trees at the same time.ElementAn instance representing a specific location in the Widget configuration tree。As time goes on, the Widget associated with a given Element may change at any time, for example, if the parent Widget is rebuilt and a new Widget is created for this location. Element makes up a tree. Most Element have a unique child ElEment, but some Widget (such as RenderObjectElement’s subclass) can have multiple sub Element.
ElementIt has the following life cycle:
  • The frame layer creates Element by calling the Widget.createElement method that is going to be used as the initialization configuration information of Element; Widget
  • The frame layer adds the newly created Element to the tree of a given slot point in a given parent by invoking the mount method. The mount method is responsible for extending any Widget to Widget and calling attachRenderObject as needed.What associated rendering objects are attached to the rendering tree.
  • At this point, Element is regarded as “activated” and may appear on the screen.
  • In some cases, the father (Element)You may change the Widget used to configure this Element, for example, because the parent Element recreates the new state. When this happens, the frame layer will call the new update method of Widget. The new Widget will always have the same as the old WidgetThe runtimeType and key attributes. If the parent Element wants to change the Widget’s runtimeType or key in this location in the tree, it can be unmounting (uninstall) the Element and expand the new Wid in this location.Get to implement.
  • At some time, the ancestor Element may decide to remove the Element (or the intermediate ancestor Element) from the tree, and the ancestor Element himself completes the operation by calling the deactivateChild. The discontinuation of the intermediate ancestor will remove this from the rendering treeElement’s rendering object, and adding this Element to the list of inactive elements in the owner attribute, allows the framework layer to call the deactivate method on this Element.
  • At this point, the Element is regarded as “invalid state” and will not appear on the screen. A Element can maintain an inactive state until the end of the current animation frame. At the end of the animation frame, any Element that is still inactive will be uninstalled.
  • If Element is recombined into a tree (for example, because it or one of its ancestors has a global key (global key) reused), the framework will remove the Element from the inactive Element list in the owner attribute and call the ElemeNT’s activate method and reattach the Element render object to the rendering tree. At this point, Element is again viewed as an active state and may appear on the screen.
  • If Element is not reassembled to the tree at the end of the current animation frame, the frame layer will invoke the unmount method of the element.
  • At this point, the element is regarded as “disabled” and will not be merged into the tree in the future.


From this we can see that Element stores Widget context and traverses the view tree, and Element holds Widget and RenderObject at the same time.


Official website definition: An object in the render tree. rendering an object in a tree. From its name, we can intuitively know that it is responsible for rendering work.
RenderObjectThere are too many attributes, and the details of this class involve a lot of rendering knowledge, and we will explain the working principles in the following series.RenderObjectThe hierarchy of the class is the core of the rendering library.
RenderObjectsThere is a parent level, and there is a slot named parentData, where parent RenderObject can store data that is specific to the child level, such as child level. The RenderObject class also implements the basic layout and rendering protocol.
However, the RenderObject class does not define a sub model (for example, if the node has zero, one or more child nodes). It does not define coordinate systems (for example, whether sublevels are located in Descartes coordinates, polar coordinates, etc.) or specific layout protocols (such as the width or size of the layout)The beam or father level sets the size and position of the sublevel before or after the sublevel arrangement; or does it really allow the child to read their parent parentData slots).RenderBoxThe subclass introduces the Descartes coordinates to the layout system.
Write a RenderObject subclass
In most cases, RenderObject itself is over class, and RenderBox will be a better starting point. However, if the rendering object does not want to use the Descartes coordinate system, it should inherit directly from RenderObject. This allows it to use an agreementA new subclass of bundles rather than the use of BoxConstraints to define its own layout protocol, and may use a new set of objects and values to represent the results of the output, not just a Size. The cost of this increased flexibility is that it can not rely on the function of RenderBox. exampleFor example, RenderBox implements an inherent size adjustment protocol that allows you to measure a sub level without fully laying, in such a way that if the sublevel changes the size, the parent will be rearranged (taking into account the new size of the sublevel). This is a subtle and error prone function.
Most aspects of writing RenderBox are also suitable for writing RenderObject, so it is recommended to read the relevant discussion of RenderBox first. The main difference lies in layout and hit tests, because these are the main aspects of RenderBox.


The layout protocol starts with the subclass of the constraint. For more information on how to write Constraints subclasses, see the discussion in Constraints.
performLayoutThe methods should be constrained and applied. The output of the layout algorithm is the field on the object, which is used to describe the object geometry of the layout of the parent object. For example, the output of using RenderBox is the RenderBox.size field. If parentUses is specified at the parent levelWhen Size is true, the output can only be read by the parent when calling the child level layout.Any rendering of any change on the object at any time will affect the layout of the object. It should call markNeedsLayout. 
FlutterThe root of the rendering object tree is a RenderView. This object has a separate child level, and it must be a RenderBox. So if you want to have a custom RenderObject subclass in the rendering tree, you have two options: you may need to replace Rend.ErView itself, or you need a RenderBox as its subclass. (the latter is more common.)
It will override the performLayout method to create a Constraints object that is suitable for your class and pass it to the layout method of the sub object.
The layout of the render object should only depend on the output of its sub layout, and only when the parentUsesSize is set to true in the layout call. In addition, if the child is set to true and the child object is rendered, the parent object must call the layout of the child object, otherwise it will be in the child pair.The parent object is not notified when the layout output is changed.
You can set up the rendering object protocol for transferring additional information. For example, in the RenderBox protocol, you can query the intrinsic size and baseline geometry of your child. However, if this is done, when the parent is using it in the last layout stage, whenever the additional information changes, the child levelYou must call markNeedsLayout at the parent level. Refer to the RenderBox.markNeedsLayout method for an example of how to implement this operation. It covers RenderObject.markNeedsLayOut, so that if the parent node queries the internal or benchmark information, it will be labeled as dirty whenever the geometric structure of the child node changes.

 Please indicate the source of the reprint

From crash_coder linguowu

Leave a Reply

Your email address will not be published. Required fields are marked *