1. Introduction

Widgets were the concept that came into contact with the most during the development of the Flutter application. The idea of Flutter is that Everything is Widget, which is to realize one of the design concepts of Flutter: Aggressive composability. Widgets are made up of a series of smaller widgets that are themselves made up of more basic widgets. For example, Padding is also a Widget, not a property in the Widget.

In Flutter, a Widget is defined as a configuration data that describes a UI element. It does not represent the display element that is ultimately drawn on the device, but only a configuration data that describes the display element. Its main functions include:

  • Describes UI controls such asText);
  • Describe the specific style of the UI (e.gColor);
  • Describe some functions (e.gGestureDetector);
  • .

2. The Widget

As is shown in the figure above,WidgetFunctionally, it can be divided into three categories:

  • Component Widget

Compose class Widgets. These widgets are used to combine other, more basic widgets to produce more complex widgets. This kind of Widget is typically used for normal business development.

  • Render Widget

Rendering widgets, which are the core widgets of the framework and participate in the layout and rendering process; Only this type of Widget is drawn to the screen.

  • Proxy Widget

The proxy Widget itself does not involve the internal logic of the Widget, but provides additional intermediate functionality for the child Widget. For example: InheritedWidget is used to pass some status information to the descendant Widget.

3. The widgets and Element

As mentioned earlier, the function of a Widget is to describe the configuration data of a UI Element, which really represents the class that displays the Element on the screen as Element. Furthermore, a Widget can have multiple elements because the same Widget object can be added to different parts of the UI tree. The introduction to Element and the relationship between widgets and Element will be covered in more detail later. Here are two things to keep in mind:

  • WidgetisElementConfiguration data,ElementIt really represents the on-screen display elements;
  • aWidgetYou can have multiple objectsElementObject.

Here is an example of a Widget object with multiple Element objects:

class SameWidgetMultiElementWidget1 extends StatefulWidget { @override _SameWidgetMultiElementWidgetState createState() => new _SameWidgetMultiElementWidgetState(); } class _SameWidgetMultiElementWidgetState extends State<SameWidgetMultiElementWidget1> { int count = 0; @override Widget build(BuildContext context) { Text testText = Text("multi element"); return Column( children: <Widget>[ testText, testText, ], ); }}Copy the code

The corresponding Widget Tree and Element Tree are as follows:

In the above example, the left isWidget TreeThe right isElement Tree. inWidget Tree,ColumnThere are two children, but they use the same child nodeTextObject, so thisTextObjects appear in two different locations (Slot), at this timeElement TreeIt’s going to produce two different onesStatelessElementObject, that is, aTextObject corresponds to twoStatelessElementObject.

4. StatelessWidget

Statelesswidgets are a common class of widgets that are suitable for scenarios where there is no need to maintain component state. Its core functions are as follows:

  • createElement

The source code is as follows:

@override
StatelessElement createElement() => StatelessElement(this);
Copy the code

This function is used to create StatelessElement and is not overwritten by ordinary users.

  • build

The source code is as follows:

@protected
Widget build(BuildContext context);
Copy the code

This function is one of the core methods of a Widget and is used to provide the user with an interface to depict the user interface. The user uses this function to compose the child widgets that the user needs, and the Framework calls this method to add the user-defined Widget combination to the Widget Tree. There are two main invocation scenarios:

  1. thisWidgetBe addedWidget Tree;
  2. thisWidgetDepencies, such as thisWidgetRely on theInheritedWidgetThe changes.

5. StatefulWidget

StatefulWidget is suitable for scenarios where the State of a component needs to be maintained. The StatefulWidget itself is immutable, but it has a mutable State. Therefore, the State it holds is often used to record State data, such as the count in a counter. Its core functions are as follows:

  • createElement

The source code is as follows:

@override
StatefulElement createElement() => StatefulElement(this);
Copy the code

This function is used to create a StatefulElement and is not overridden by ordinary users.

  • createState

The source code is as follows:

@protected
@factory
State createState();
Copy the code

This function is used to create the corresponding State. The user can create the State whose data needs to be saved by this method. The Framework may call this function multiple times during the life of a StatefulWidget. For example, if a StatefulWidget is added to multiple locations in the Widget Tree, the Framework will create a separate State for each location.

6. State

State indicates the information to be saved by the corresponding StatefulElement. It has the following features:

  1. In the correspondingWidgetCan be read synchronously at build time;
  2. In the correspondingWidgetMay change during the life cycle of. Developers need to make sure that theStateIs called when a change occursState.setStatenoticeFramework.FramenworkWhen the message is received, it will be called againbuildMethods reconstructionWidget TreeTo update the UI.

The main functions of the State life cycle are as follows:

  • initState

This callback is called when the Widget is first inserted into the Widget Tree. The Flutter Framework calls this callback only once for each State object, so it usually does one-time operations such as State initialization, subscribing to subtree event notifications, and so on.

  • didChangeDependencies

Called when the dependencies of the State object change; There are two main scenes:

  1. Its reliance on theInheritedWidgetThe object has changed.
  2. First insertionWidget Tree, in theinitStateAfter.
  • build

This callback, which readers should be familiar with by now, is primarily used to build Widget subtrees and is called in the following scenarios:

  1. In the callinitStateAfter.
  2. In the calldidUpdateWidgetAfter.
  3. In the callsetStateAfter.
  4. In the calldidChangeDependenciesAfter.
  5. inStateObject is removed from a location in the treedeactivate) and then reinserted into the rest of the tree.
  • reassemble

This callback is provided specifically for development debugging purposes and is called on a hot reload. This callback is never called in Release mode.

  • didUpdateWidget

When the Widget is rebuilt, the Flutter Framework calls Widget.canUpdate to detect new and old nodes at the same location in the Widget Tree and then determine whether an update is needed. This callback is called if Widget.canUpdate returns true.

  • deactivate

This callback is called when the State object is removed from the tree. In some scenarios, the Flutter Framework will reinsert the State object into the tree, such as when the subtree containing the State object moves from one place in the tree to another (this can be done via GlobalKey). The Dispose method is called immediately after the removal if it is not re-inserted into the tree.

  • dispose

Called when the State object is permanently removed from the tree; Resources are usually released in this callback.

StateThe lifecycle is as follows:

7. RenderObjectWidget

RenderObjectWidget provides the configuration for RenderObjectElement and is the Widget that is really responsible for rendering. Its core functions are as follows:

  • createRenderObject

This function is used to create the corresponding RenderObject.

  • updateRenderObject

This function is used to update the corresponding RenderObject based on the configuration of the Widget. Note that this function should not update RenderObject children.

  • didUnmountRenderObject

This function is used to clear the RenderObject’s resources when it is removed from the tree.

Nodule 8.

This article introduces the types of widgets and their core functions. The highlights are as follows:

  • WidgetIs defined as the configuration data that describes a UI element. It does not represent the display element that is ultimately drawn on the device, but only a configuration data that describes the display element.
  • WidgetThere are three main categories:Component Widget,Proxy WidgetAs well asRender WidgetOf which onlyRender WidgetBefore participating in the layout and paint process.
  • aWidgetYou can have multiple objectsElementObject.

9. Reference documents

2. The Actual combat of the Flutter

10. Related articles

Framework Analysis of Flutter (1) — Overview Of Flutter Framework Analysis (3) — Element Framework Analysis (4) — RenderObject Framework Analysis (5) — Widget, Element, Element RenderObject Tree Flutter framework analysis (6) -Constraint Flutter framework Analysis (7) -relayoutBoundary Flutter Framework Analysis (8) -Platform Channel Flutter framework Analysis – Parent Data Flutter framework Analysis -InheritedWidget