This is the 28th day that I participated in the August More Text Challenge
The principle and use of Flutter Key
In the last article, we encountered a problem where the position of the widget changed and something happened that didn’t switch the position as we expected. We got confused because we thought that if we wrote a widget, the widget should be displayed as we intended. Widgets are not the things that end up on the screen.
Widget Tree
Some of you may have heard of a Widget Tree, which is something that has widgets nested inside it. Take this code for example:
Column(
children: [
Box(Colors.blue),
Box(Colors.red),
],
)
Copy the code
The corresponding Widget Tree looks like this:
- Column
- Box
- Box
Copy the code
But it’s not the Widget Tree that’s actually drawn on the screen. We all know that Wdiget describes the configuration of the UI Element Element Element, so when it actually runs, it also generates an Element Tree, An Element Tree is an object generated after the Widget Tree is instantiated.
Widget Tree — Instantiate –> Element Tree
- column-columnelite-box - instantiate -> -boxElite-box - BoxElementCopy the code
Widgets are responsible for rendering, such as color, size, shape, and so on.
Element manages the state inside.
So the state changes with the Element, and the appearance changes with the Widget. The two are separate.
Why are they separated?
Because widgets are immutable, we might often see a prompt like this:
Immutable, meaning that once created it cannot be changed at run time, but State can be changed. Usually we use setState to notify a flutter to rebuild a new widget, not to change it, because the widget is immutable. But getting rid of the widget doesn’t get rid of the state.
Since most of the UI design is done by changing widgets, if we can separate the Widget from the State, during hot Reload, we can keep the State of the Widget while changing it. If the state was dropped every time the widget changed, the application would be unusable, with no way to support Hot Reload and animation effects.
Why change the order of widgets, but not the order on the UI
So when Wdiget changes, we try to associate it with the original State.
How does it relate?
When the Widget changes,flutter will check to see if Wdiget and the Element are the same. For example, if Columen is changed to Row, they are different. Flutter will then check to see if the Key is the same . Of course, if you don’t pass the key, it won’t be able to compare the key, and if the widget doesn’t change, it will still use the original Element.
It’s kind of like determining whether two objects are equal by comparing their types.
Therefore, if we transposes the position of the Box, for example, if there are two boxes on it, the Widget Tree will be of the same type, so that the BoxElement will correspond to the previous Box, so that the Flutter will think that there is no change.
So when we made the following changes:
Column( Column(
children: [ children: [
Box(Colors.blue), -> Box(Colors.red),
Box(Colors.red), Box(Colors.blue),
] ]
Copy the code
Flutter simply changes the top Widget to red and the bottom Widget to blue. It doesn’t seem a problem to look at it that way.
Now, let’s look at the case where we have a Key
-column-columnelite-box (Key1) -instantiation -> -boxElement (Key1) -box (Key2) -boxElement (Key2)Copy the code
Switch the upper and lower boxes, The first BoxElement when comparing keys after comparing the same type (Key1) If the corresponding key of the Box is not the same, the Flutter will search other widgets at the same level to see if they have the same key. Then the Flutter will find a corresponding Box below, and the same search method for the Box below.
So this is what the change looks like:
-column-columnelite-box (Key2) -instantiation -> -boxElement (Key1) -box (Key1) -boxElement (Key2)Copy the code
This allows a Flutter to swap states. A Flutter can track changes in order with the help of a Key.
What if we delete one of them like we did before?
Column(
children: [
Box(Colors.blue),
Box(Colors.red),
],
)
Copy the code
After deleting the first one, it becomes:
Column(
children: [
Box(Colors.red),
],
)
Copy the code
So the red box becomes the first one. The original
- ColumnElement
- BoxElement
- BoxElement
Copy the code
The first BoxElement corresponds to the red Box, the second is not found, and it is discarded.
In the case of a Key, if the first Element goes to the Widget and the first Key doesn’t match or the sibling doesn’t match, it’s discarded, and the second Element matches the first one, and the change is as expected.
The same goes for adding a Wdiget. Because elements are found from top to bottom, if there is no key, a new widget of the same type will replace the widget in the previous location and correspond to the Element. If the widget in the last location has no corresponding Element, it will call createState to create a new St ete.