“This is the 13th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021”

Yesterday we talked about the flutter three trees (widgets, element, renderObject), due to the space without detailed sauce element life cycle, today we’ll look at the life cycle of the element

Element life cycle

By looking at the Element class we can see that it is an abstract class:

abstract class Element extends DiagnosticableTree implements BuildContext { Element(Widget widget) : assert(widget ! = null), _widget = widget; Element _parent; @override Widget get widget => _widget; Widget _widget; RenderObject get renderObject { ... } @mustCallSuper void mount(Element parent, dynamic newSlot) { ... } @mustCallSuper void activate() { ... } @mustCallSuper void deactivate() { ... } @mustCallSuper void unmount() { ... }Copy the code

And contains the following four lifecycle methods

  1. mount
  2. activate
  3. deactivate
  4. unmount

Create Element

An Element instance is created when the widget calls createElement

mount

When element.mount is called, the mount method first calls createRenderObject to create the renderObject and then calls attachRenderObject to add the previously created renderObject to the renderTree, so el Ement is in the active state, and the active state is displayed on the screen

When a widget is updated, the updateChild method is called to avoid re-creating an Element to determine whether it can be updated

@protected Element updateChild(Element child, Widget newWidget, dynamic newSlot) { if (newWidget == null) { if (child ! = null) deactivateChild(child); // Return null if there is no new control and the original control exists; } Element newChild; if (child ! HasSameSuperclass && child.widget == newWidget) {// Update child if (child.slot! = newSlot) updateSlotForChild(child, newSlot); newChild = child; } else if (hasSameSuperclass && Widget.canUpdate(child.widget, NewWidget) {/// The same parent control type, and can update widgets, update child if (child.slot! = newSlot) updateSlotForChild(child, newSlot); child.update(newWidget); assert(child.widget == newWidget); newChild = child; } else {//// can not be updated, you need to remove the original child, then create a new child and add deactivateChild(child); assert(child._parent == null); newChild = inflateWidget(newWidget, newSlot); }} else {// create a newChild and add newChild = inflateWidget(newWidget, newSlot); } return newChild; }Copy the code

Widget. canUpdate is used to check whether the runtimeType and key are the same, so we can specify a different key if we want to force the update. We do not recommend changing the runtimeType

If the parent wishes to change the runtimeType or key of the widget at this location in the tree, can do so by unmounting this element and inflating the new widget at this location.
Copy the code

activate

Add Element’s Render object back to the RenderTree

void activate() { assert(_debugLifecycleState == _ElementLifecycle.inactive); assert(widget ! = null); assert(owner ! = null); assert(depth ! = null); assert(! _active); final bool hadDependencies = (_dependencies ! = null && _dependencies.isNotEmpty) || _hadUnsatisfiedDependencies; _active = true; // We unregistered our dependencies in deactivate, but never cleared the list. // Since we're going to be reused, let's clear our list now. _dependencies? .clear(); _hadUnsatisfiedDependencies = false; _updateInheritance(); assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; } ()); if (_dirty) owner.scheduleBuildFor(this); if (hadDependencies) didChangeDependencies(); }Copy the code

deactivate

In the updatechild method we see that if the new widget is empty and an old widget exists, deactivateChild is called to remove the child, and then the deactivate method is called to set the _debugLifecycleState state to inactive

// remove element @mustcallsuper void deactivate() {if (_dependencies! = null && _dependencies.isNotEmpty) { for (final InheritedElement dependency in _dependencies) dependency._dependents.remove(this); } _inheritedWidgets = null; _active = false; }Copy the code

unmount

When the inheritedWidget and active are reworked, the unmount method is called to remove the element

conclusion

Ok, today’s source view is over here, as a student of Flutter, I hope you can give me more advice and discuss with me where there are problems