Today we are going to create the following layout using Flutter. Why should we do that? The answer is simple: “practice makes perfect”.
But how could we do that? Is it really possible to twist squares over and under each other like that?
The first method that comes to my mind is using nine squares, and colouring them accordingly, like this:
But is it possible to use fewer squares? Maybe like this:
The above layout consists of one column that wraps everything else. In that column, there are two rows. The first row has two children (red and orange), and the second row has two columns. The first column is green and the second column has two rows, and so on…
As far as I know, it’s not possible to use one single widget for the orange block, unless… we use a stack, and arrange the orange block on top of the other ones.
So first let’s create the above layout and after that, we will see how to use a stack for the orange one.
In the first
Row, we will create two “Container”s and will wrap each of them in an
Expanded widget, setting the flex factor to 2 for the red
Container and 1 for the yellow one. I will also set their height to 100.
Using an Expanded widget makes a child of a Row or Column expand to fill the available space in the main axis (e.g., horizontally for a Row or vertically for a Column). If multiple children are expanded, the available space is divided among them according to the flex factor.
Now let’s create the second row.
For the second row, we will use another two Expanded widgets as well, the first one with flex factor 1 and the second one’s flex factor will be 2.
In this row, we will put the purple and orange blocks in two Expanded widgets. But we won’t specify the flex factor for them. Therefore they will occupy the available space equally:
The result is:
To show the white numbers on each block, simply put a Text widget as the child of each Container, for example for the red Container we will have:
And notice that I have wrapped the Text widget in a Center widget so that the text is shown in the center of the container:
We are almost done, except that “2” number, which is centered, but it’s not centered! That orange block consists of two different containers, and the number “2” has been centered in the lower container!
How’d we align this number to make it centered as well?
I am following a channel on youtube created by the creators of Flutter called “Flutter Widget of the Week”. I totally recommend you to follow it if you haven’t already! In the last episode, they introduced the “Align” widget, which will be very useful here for us. Let’s watch the video, it’s only 1 minute and 22 seconds:
As you can see in the following picture, if we set the alignment to (0, -1), the object will be placed in the top center position inside its container:
I used this to align the text inside the lower orange block.
I also tried setting the alignment value to (0, -2.5) to move the object even upper (and actually outside) its container, and it worked as well:
Now let’s create everything from scratch with the “Stack” widget.
Children of Stack are positioned from bottom up. So the first child that should go under others is the purple one, number 5:
Now let’s add the second child of the stack, block number 1:
Note that I have used the
MediaQuery class to get the width of the screen and then multiplied it by 2/3. Alternatively, I could wrap the container in a
FractionallySizedBox class with
widthFactor of 0.66 (2/3) to achieve the same width for the red block. Also, note that the children of a stack are by default positioned at the top left corner of the stack. Therefor we do not need to align the red block:
Now we will put the orange block on the stack:
Note that this time, I’ve wrapped the whole
Container in an
Align widget, to move the widget to the upper right corner of the stack. And this time, the width of the orange block is 1/3 of the whole screen width:
Adding and positioning the blue block is a little tricky. Because if you align it to “bottomRight”, it will end up like this:
This is because we have not specified any size for our stack. And therefore it has expanded itself to the size of the whole screen. Now we have two options to align the blue block:
- Restrict the height of the
Stack. By wrapping it in a
SizedBoxwidget, and setting the
heightproperty to 300.
- Align the blue block manually. i.e. use
alignment: Alignment(1, -0.22)instead of
I choose to implement the first one:
Placing the last child on the stack is almost like the previous one, the only difference is its width, which is set to 1/3 of the screen width, and its position which is lower left, or bottmStart:
MediaQueryclass is very useful for responsive design. You can use it to find out about the total size of the screen, and then setting the size of your widgets accordingly.
Expandedwidget is also very handy in responsive design, making your widgets fill the remaining space by the
flexfactors you specify.
- When you want to position your widget in its parent, wrap the widget in an
Alignwidget, and set the
- If you don’t specify the width and height for any of the Stack’s children, by default they will expand themselves to the width and height of the Stack.
- You could also wrap each child of the Stack in a Positioned widget to align them.
The whole source code can be found on github.
Thanks for reading!