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.
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.
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.
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.
|depth||int||The depth of the tree root Element must be greater than 0|
int get depth => _depth;
|dirty||bool||If Element has been marked for reconstruction, return to true|
bool get dirty => _dirty;
@overrideint get hashCode => _cachedHash;
|owner||BuildOwner||Managing the Element lifecycle|
@overrideBuildOwner get owner => _owner;
|renderObject||RenderObject||If 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.|
|widget||Widget||The configuration information of this Element|
@overrideWidget get widget => _widget;
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.
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.
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.
Please indicate the source of the reprintFrom crash_coder linguowu firstname.lastname@example.org