In Flutter, everything is a widget. Gestures are a widget, animation is a widget, and UI is even more of a widget. Today we will talk about a particular one of the Widgets, Container.
1. References
Container is easy to use at first, but its logic is a bit complicated. I can’t say THAT I fully understand it. Therefore, the initial version of this article mainly summarizes various articles on the Internet and adds my own understanding
The Widget that gets onto the car quickly
Container class
Building Layouts in Flutter
Dealing with box constraints in Flutter
Flutter — Container Cheat Sheet
Widgets: Container
What is a Container in Flutter?
Container Widget with example Flutter Tutorial
Container Widget In Flutter
Understanding Flutter Layout (Box)Constraints
2. Introduction
In Flutter, all functions are scattered into widgets with a single function, such as Center, Padding, Text and GestureDetector. They each maintain a function, but the UI of our commercial apps is beautiful. To achieve a good layout, you need to nest a lot of layout widgets, so Container comes into being:
A convenience widget that combines common painting, positioning, and sizing widgets.
Hit the official documentation on the container of complex reasons, it is a convenient unit, a blend of components, graphics, positioning and size, as far as I know, you can set the size, background color, border, rounded corners, shadow, gradient, there are many kinds of situation, and the size can sometimes depend on the parent widget, and sometimes depends on the child widgets, sometimes rely on myself, We will focus later on the layout of containers (regular size, width and height).
3. Widget rendering process
4. Container rendering process
According to the Container, the Container first uses the padding set to surround the child parts, then adds additional constraints on the padding size (if not empty), and then the Container is surrounded by an outer margin. During the drawing process, the Container first applies a transform, then draws decorations to fill the area, then draws sub-components, then foreground decorations, and fills the area.
Decoration and foregroundDecoration are fill configurations. The former is below the subcomponents and the latter is above the subcomponents. You can set fill colors, borders, fill shapes, shadows, gradients, background images, etc.
If the constraints of the Container are limited, a Container without child parts will try to be as large as possible, and if the constraints of the Container are unbounded, it will try to be as small as possible.
A Container that has child components determines its size based on the child components.
5. There is no limit
What are restricted and unrestricted constraints, and what are the various parts?
In a flutter, the widgets are rendered by the underlying RenderBox. The parent component provides constraints to the RenderBox. The RenderBox then adjusts its Size with these constraints.
In general, there are three types of boxes that handle constraints:
- As large as possible: Center and ListView, etc
- Same size as the sub-components: Transform and Opacity, etc
- Specific size: Image, Text, etc
- Special cases: Row and Column are determined by their given constraints, and Container is determined by arguments to its constructor
However, constraints can sometimes become compact, meaning that it does not leave the rendering box to decide on its own size (for example, the maximum width is equal to the minimum width, which is a fixed value), such as the App Widget, where the constraint is set to a fixed size of the application content (i.e., the entire screen). In Flutter, many widgets, especially those that can only have one child, will pass their constraints to the child. That is, if you have a set of widgets nested in your App’s root render tree, they will be placed one at a time due to tight constraints.
However, some widgets make constraints loose, meaning that maximum constraints remain but minimum constraints are removed, such as Center.
5.1 Unlimited Restrictions
- In some cases, the constraints given to widgets are unbounded, or infinite. In other words, the maximum width and maximum height are double.INFINITY.
- A widget that tries to be as big as possible will not work when it encounters unlimited constraints because it does not know how big it should be. In debug mode, exceptions will be thrown.
- The most common cases of having unlimited constraints are embedded in elastic boxes such as rows, columns, or scrollable areas (ListView or other ScrollView subclasses).
It is important to note that the ListView will expand to the parent boundary in the direction of its intersection, such as a list scrolling vertically, and try to be as wide as the parent horizontally. When you embed a scrolling list inside a scrolling list, the scrolling list is going to be as wide as it can be, which is infinitely wide, because scrolling lists are infinitely wide, which is not normal.
In addition, elastic boxes (Row and Column) behave differently under restricted and unrestricted constraints.
- When constrained, they will be as large as possible in their direction.
- In the case of unrestricted constraints, they accommodate their child components in their direction (enveloping their child components). In this case, you can’t use Expanded in elastic boxes because it will not be possible to determine the size of the parts.
6. Container Layout (Size rules)
The layout of a Container is a bit complicated because it combines the functions of other parts. In short, in order, a Container will:
- Follow alignment rules
- Resize itself for child parts
- Follow the width, height and constraints
- Then the Container tries to be as small as possible.
6.1 Take a look at the explanation of the official documentation (if you don’t understand this explanation, it is a bit wordy) :
- If the Container has no children, no width, and no constraints, and the parent provides unbounded constraints, the Container will be as small as possible.
- If a Container has no child parts and no alignment rules, but provides height, width, or constraints, then the Container will be as small as possible following the width, height, constraints, and parent constraints.
- If the Container has no children, no width, no constraints, and no alignment, but the parent provides constraints, then the Container expands to fit the parent constraints
- If the Container has an alignment rule and the parent provides unlimited constraints, the Container will try to adjust itself to surround the children
- If the Container has an alignment rule and the parent provides constraints, the Container will try to expand to fit the parent and then place the children within it based on the alignment
- In addition, a Container has children, but it has no width, height, constraints, or alignment rules. The Container passes the parent’s constraints to its children, and then adjusts itself to match the children.
- Margin and padding will also affect the layout, decoration will add padding implicitly (e.g. border).
- The default is as large as possible
6.2 Let’s summarize:
maxWidth | maxHeight | The constraint | With or without subcomponents | Layout rules |
---|---|---|---|---|
Have a value | Have a value | There are limits | There is no | As large as possible |
Have a value | There is no value | Height is unlimited, width is limited | There is no | Keep the height as small as possible and the width as wide as possible |
There is no value | Have a value | Height is limited, width is unlimited | There is no | The height is as large as possible and the width is as small as possible |
There is no value | There is no value | unlimited | There is no | As small as possible |
Will do | Will do | Will do | There are | As small as possible to satisfy the constraints |
6.3 example
There are no subcomponents, there are constraints, as large as possible ↓
There is no child component, the maximum width of the parent component constraint is the width of the screen, and the maximum height is infinite. The minimum width of its own constraint is 100, and the minimum height is 100, then the height is as small as possible, and the width is as large as the screen width ↓
The maximum constraint of the parent component is the width of the screen. If the parent component has a fixed width of 100, the width is 100. The height of the parent component can be as large as the screen height ↓
There is no constraint set by ourselves, there is a child component, so we wrap the child component ↓
If there are sub-components, the height is 100 and the width covers the sub-components ↓
If the width is set to infinite, the height is set to 100. The width is the constraint screen width of the parent component ↓
7. To summarize
Container should be the most flexible layout widget in FLUTTER. It is important to use Container wisely. Otherwise, your code will become unreadable and difficult to maintain