Read the demo of Flutter layout constraints carefully to gain a better understanding of the layout

The layout of Flutter is quite different from that of HTML (these developers are probably Web developers). Then memorize this rule:

First, the upper widgets pass constraints to the lower widgets; The lower-level widgets then pass size information to the upper-level widgets. Finally, the upper-layer widgets determine the location of the lower-layer widgets. Constraints go down. Sizes go up. Parent sets position.

If we don’t master this rule in development, we won’t fully understand it in layout, so the sooner we learn it, the better!

More details:

  • A Widget gets its own constraints from its parent. The constraint is essentially a collection of four floating-point types: maximum/minimum width, and maximum/minimum height.
  • The widget will then iterate through its children list one by one. Pass the constraints to the children (constraints may vary between the children), and then ask each of its children how big they need to be for the layout.
  • The widget will then have children of itchildrenLayout one by one. The horizontal direction isxThe axis, the vertical isyAxis)
  • Finally, the widget will pass its size information up to the parent widget (including its original constraints).

For example, if a widget contains a Column with padding, and the Column’s child widgets are laid out as follows:

The negotiation would look something like this:

Widgets: “hey! My father. What are my constraints?”

Parent: “You have to be 80 to 300 pixels wide and 30 to 85 pixels tall.”

Widgets: “HMM… I want a 5-pixel inner margin so that my children can be up to 290 pixels wide and 75 pixels high.”

Widget: “Hey, my first child, you have to be 0 to 290 wide and 0 to 75 long.”

First Child: “OK, I want 290 pixels wide and 20 pixels long.”

Widgets: “HMM… Since I want to put my second child below the first, we only have 55 pixels left for the second child.”

Widget: “Hey, my second child, you have to be 0 to 290 in width and 0 to 55 in length.”

Second Child: “OK, I want 140 pixels wide and 30 pixels long.”

Widget: “Good. My first child will be placed at x: 5&y: 5 and my second child will be placed at X: 80&Y: 25.”

Widget: “Hey, my parent, I decided to make my size 300 pixels wide and 60 pixels high.”

limit

As mentioned in the layout rules introduced above, the layout engine of Flutter has some important limitations:

  • A widget can only determine its size if its parent restricts it. This means that widgets generally cannot be as large as they want.
  • A widget cannot know and does not need to determine its position on the screen. Because its position is determined by its parent.
  • When it is the parent’s turn to determine its size and position, it also depends on its own parent. So, it’s almost impossible to define exactly the size and location of any widget without considering the entire tree.
  • If a child wants to have a different size than its parent, but the parent does not have enough space to lay it out, the size of the child may not take effect. Specify its alignment explicitly

Tight vs. loose constraints

You’ll often hear about constraints that are strict or loose, and it’s worth your time to figure them out.

Tight constraints give you an option to get the exact size. In other words, it has the same maximum/minimum width and the same height.

If you search for the BoxConstraints constructor in the box.dart file of Flutter, you will find the following:

BoxConstraints.tight(Size size)
   : minWidth = size.width,
     maxWidth = size.width,
     minHeight = size.height,
     maxHeight = size.height;
Copy the code

If you reread Sample 2, it tells us that the screen forces the Container to be as big as the screen. The reason screens can do this is because they pass strict constraints to the Container.

A loose constraint, in other words, sets the maximum width/height, but allows its child widgets to be any size smaller than it is. In other words, the minimum width/height of the loose constraint is 0.

Loose (Size Size) : minWidth = 0.0, maxWidth = size.width, minHeight = 0.0, maxHeight = size.height;Copy the code

If you go to Sample 3, it will tell us that Center makes the red Container smaller, but does not exceed the screen. The reason Center can do this is because it gives the Container a loose constraint. In general, the Center’s role is to take strict constraints from its parent (screen) and translate them into loose constraints for its children (Container).

Know how to make layout rules for a particular widget

Knowing the general layout is important, but it’s not enough.

When applying general rules, each widget has a great deal of freedom, so there is no way to know what a widget might look like just by looking at its name.

If you try to guess, you might be wrong. Unless you have read the widget’s documentation or studied its source code, you cannot know for sure how the widget behaves.

Laying out the source code is often complex, so reading the documentation is a better choice. But when you’re exploring the layout source code, you can easily find it using the IDE’s navigation features.

Here’s an example:

  • Find one in your codeColumnAnd follow up to its source code. To do this, use it in (Android Studio/IntelliJ)command+B(macOS) orcontrol+B(Windows/Linux). You will jump tobasic.dartFile. Due to theColumnExtend theFlex, please navigate toFlexSource code (also locatedbasic.dart).
  • Scroll down until you find one namedcreateRenderObject()Methods. As you can see, this method returns oneRenderFlex. It is aColumnRender object, now navigate toflex.dartIn the fileRenderFlexSource code.
  • Scroll down until you find itperformLayout()Method that performs the column layout.