Flutter – what are widget, renderobject and element

Time:2021-4-18

The original text is inhere

This article explains in detail how to turn a widget into pixels on the screen

If you want to be a better developer, it is almost essential to understand the underlying implementation technology. You can easily create custom layouts and special effects if you learn how these underlying technologies work. Can also let less in front of the computer to add a few nights of class.

The purpose of this article is to introduce the technology under flutter and let you understand how it works.

##Let’s start now

You may already know how to use statelesswidget and statefulwidget. But these widgets just put other widgets together. The layout and drawing on the screen takes place elsewhere.

**I strongly recommend that you open your favorite editing tool, and then follow this article step by step to see how the actual code is implemented, and “so it is” along the way. 、

##Opacity component
It’s best to start with the component of opacity. This widget is simple enough and a great example.

It accepts only one subcomponent. So you can put any widget into opacity and change its display. There is another valueopacity, between 0.0 and 1.0. It’s used to control transparency.

OpacityyesSingleChildRenderObjectWidgetSubclass of. The path of inheritance is as follows:

Opacity -> SingleChildRenderObjectWidget -> RenderObjectWidget -> Widget。

andStatelessWidgetandStatefulWidgetThe path of inheritance is as follows:

StatelessWidget/StatefulWidget -> Widget

The difference is that statelesswidget and statefulwidget just combine different components (widgets), while the opacity component controls how a component is drawn.

But if you want to find some clues to draw pixels from the code of opacity, it’s almost futile. This is because a widget only contains configuration information, such asOpacityComponent contains only one value of opacity.

That’s why you can create abuildMethod to create a new widget, which does not contain the code of building components that consume resources, only contains some information needed for building.

draw

What happens when you draw?

RenderObject

It’s all thereRenderObjectIt’s going on in the hotel.This list can also be known from the name. The opacit component creates and updates the renderobject in this way:

@override
RenderOpacity createRenderObject(BuildContext context) => new RenderOpacity(opacity: opacity);

@override
void updateRenderObject(BuildContext context, RenderOpacity renderObject) {
  renderObject.opacity = opacity;
}

RenderOpacity

OpacityA component sets its own size to the same value as the size of its child components. It’s basically the same as every aspect of its subcomponents, except drawing. The opacity value is added before drawing the subcomponents.

In this case,RenderOpacityYou need to implement all the methods (for example, perform layout, collision detection, and size calculation) and leave them to subclasses to perform specific work.

RenderOpacityInheritedRenderProxyBoxThis class mixins some other classes. These classes implement the methods mentioned above.

double get opacity => _opacity;
double _opacity;
set opacity(double value) {
  _opacity = value;
  markNeedsPaint();
}

I (the author) deleted most of the code, to see all the code can be in thehereLook.

Getter exposes private values. The setter will callmarkNeedsPaint()perhapsmarkNeedsLayout(). As the name suggests, it informs the system that “this component has changed and needs to be redrawn or rearranged.”

stayRenderOpacityThere are also the following codes:

@override
void paint(PaintingContext context, Offset offset) {
    context.pushOpacity(offset, _alpha, super.paint);
}

PaintingContextIt’s a canvas. There’s a method on this canvas calledpushOpacity

This line is the concrete implementation of opacity.

review

  • OpacityNot oneStatelessWidgetperhapsStatefullWidgetIt’s aSingleChildRendeObjectWidget
  • Component only contains the information needed for drawing. For example,OpacityComponent contains aopacityValue.
  • RenderOpacity, inherited fromRenderProxyBoxThe specific layout and drawing actions are carried out
  • Because the opacity component is basically the same as its subcomponents, it represents all the methods of its subcomponents
  • It override the paint method, which adds a specific opacity value to the subcomponents of opacity

Is that all?

Remember that a widget is just a configuration,RenderObjectIt’s about managing layout and drawing.

In flutter, you basically create new widgets all the timebuild()When the method is called, you create a lot of components. When something changes, the build method is basically called. For example, in an animation, the build method is often called.It’s better not to redraw the whole subtree every time. The update will be better.

You can’t get the size or position of a component on the screen, because a component represents a blueprint, which is not actually drawn on the interface. It only contains the information needed by render object.

Element

An element is the actual component of a component tree.

What happened?

The first time a component is created, an element is created, and the two are related to each other. The element is then inserted into a tree. If the component (widget) changes, it will compare with the old component and update the corresponding element. The most important thing is that the element will not be re created at this time, it will only be updated.

Element is part of the core of flutter, but there’s no need to know more about it now. That’s enough.

Where was the element of the opacity component created

Please have a look. staySingleChildRenderObectWidgetin

@override
SingleChildRenderObjectElement createElement() => new SingleChildRenderObjectElement(this);

SingleChildRenderObjectElementIt’s just an element with a child.

Element create renderobject

If the element creates the renderobject, how can the renderobject of the opacity component be created by itself?

Basically because the opacity component just needs aRenderObjectBut you don’t need a custom element.

Look at the following code:

SingleChildRenderObjectElement(SingleChildRenderObjectWidget widget) : super(widget);

SingleChildRenderObjectElementThere is oneRenderObjectWidgetReference to (also includes creatingRenderObjectIn this way.

stayRenderObjectElement#mountMethod, element is inserted into the element tree

@override
void mount(Element parent, dynamic newSlot) {
  super.mount(parent, newSlot);
  _renderObject = widget.createRenderObject(this);
  attachRenderObject(newSlot);
  _dirty = false;
}

When the element is mounted, it will let the component create a render object.

last

This is how the opacity component works.

My goal is to use this article to introduce the principles under components. There is still a lot of content not covered, but I hope this article can at least give you a glimpse.

Recommended Today

Deeply analyze the principle and practice of RSA key

1、 Preface After experiencing many dark moments in life, when you read this article, you will regret and even be angry: why didn’t you write this article earlier?! Your darkest moments include: 1. Your project needs to be connected with the bank, and the other party needs you to provide an encryption certificate. You have […]