Widgets are considered the building blocks of the Flutter UI. Every thing in Flutter is considered as a widget. From Text to image to more complex blocks are all widgets. Moreover, some of the widgets provided by Flutter are for the purpose of laying out the UI which are usually not quite visible. These widgets include Row, Column, Stack, Expanded, Padding, Center, Container, SizedBox, and so on. Flutter layouts help you define the structure of your application’s UI. Some of these layouts are single child layouts, while others are multiple child layouts.
So without further ado, let’s dive into Flutter layouts deeper to learn how to use them.
Container
A container is a single child box-based widget which means it only takes one widget as its child. The benefit of container is that it allows you to customize its child widget to control its border, margin, padding, alignment, background color and so much more styling features.
Some of the most useful properties of a Container are:
- child
specifies the child widget to be displayed within the container. This can be any widget such as text, image, row, column, stack, etc - padding
specifies the padding to control the space between the border of the container and its child widget. Here, we need to have an EdgeInsets attribute to choose the desired side to specify the padding to.
For example, EdgeInsets.all to specify one padding value to be assigned to all sides including top, left, right, and bottom. Another example is EdgeInsets.only which allows you to specify an individual value for each side separately. - margin
This specifies the empty space value around the container. like the padding, we also need to add EdgeInsets attribute to choose where to apply the margin to. - width and height
These values are to control the size of the container and they’re specified separately. - color
as its name suggests, this property is to set the background to the container. Here, we use the attribute Colors to choose which color we desire. For Instance, Colors.black to apply a black color for the container background - alignment
This property is to set the position of the container’s child. It takes values like Alignment.center, Alignment.topLeft, etc. - decoration
This property is to add some decoration to the container to enhance its appearance. It allows you to add various decoration using the BoxDecoration widget which contains a variety of parameters to draw a box.Some of these parameters are:
- border
This property is to specify the color and width of the border - shape
specifies the shape of the box. For example, you can set the shape to circle using BoxShape.circle or to a rectangle using BoxShape.rectangle - borderRadius
This is to control the roundness of the box corners. For example, boxRadius.circular(25) to give the box a more rounded corners. - color
This property is to set the color of the box. Take note that if you use the color property outside the decoration property, the container’s color, an error will occur. Once you add the decoration parameter to the container, you’re required to set the color within the BoxDecoration itself.
- border
Example
Container( width: 300, height: 300, alignment: Alignment.center, padding: EdgeInsets.all(20), margin: EdgeInsets.symmetric(horizontal: 50, vertical: 30), decoration: BoxDecoration( color: Colors.red, shape: BoxShape.circle, //borderRadius: BorderRadius.circular(25) ), child: Text( 'Hello World!', style: TextStyle( fontSize: 30, fontWeight: FontWeight.bold, color: Colors.white, ), ), )
Output

Row
Row is a multiple child widget that lays other widgets within it, its children, in a horizontal direction. It allows you to position widgets next to each other in one row.
Some of the properties that a Row widget takes are:
- children[]
This property is a list of widgets to be displayed within the Row layout. - mainAxisAlighment
Identifies how children are placed along the main axis. It takes arguments such as start, end, center, spaceAround, spaceBetween, and spaceEvenly.
For example, mainAxisAlignment: MainAxisAlignment.start displays the widgets in the Row beginning from the most left side of the row. - crossAxisAlignment
In contrast with mainAxisAlignment, crossAxisAlignment identifies how children are placed along the cross axis. the arguments this property takes include start, end, center, baseline, and stretch.
For example, crossAxisAlignment.center will display the child in the center (vertically). - mainAxisSize
Specifies the space to be occupied in the main axis for. This means minimizing or maximizing the remaining space within the row. - textDirection
determines the order of which the children are arranged.
Example
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.thumb_up, color: Colors.indigo, size: 30), Icon(Icons.comment, color: Colors.indigo, size: 30), Icon(Icons.share, color: Colors.indigo, size: 30), ], ),
Output

Column
Column is another multiple child widget that allows you to put one widget after another, arranging them vertically (opposite of a row). In other words, column is a linear layout with its children in vertical orientation.
Some of the properties a Column takes:
- children[]
Similarly to Row, A column takes a list of widgets to display within it. - mainAxisAlignment
Identifies how children are placed along the main axis. - crossAxisAlignment
Identifies how children are placed along the cross axis of the column. - mainAxisSize
Specifies the space to be occupied by the remaining space of the column - textDirection
determines the order of the column children
Example
Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.thumb_up, color: Colors.indigo, size: 30), SizedBox(height: 10), Text('Like', style: TextStyle(color: Colors.indigo, fontSize: 18),) ], ),
Output

Nested Column and Row
One important thing to realize is that you can merge columns and rows to build a more complex Flutter layouts. In fact, columns and rows are one of the most used layouts in flutter.
Example
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.thumb_up, color: Colors.indigo, size: 30), SizedBox(height: 10), Text('Like', style: TextStyle(color: Colors.indigo, fontSize: 18),) ], ), Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.comment, color: Colors.indigo, size: 30), SizedBox(height: 10), Text('Comment', style: TextStyle(color: Colors.indigo, fontSize: 18),) ], ), Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.share, color: Colors.indigo, size: 30), SizedBox(height: 10), Text('Share', style: TextStyle(color: Colors.indigo, fontSize: 18),) ], ), ], )
Output

Expanded
Expanded widget is another Flutter layout that you can use to make a child of a Column or a Row occupy all the available area within the parent widget.
Example
Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 50, height: 50, decoration: BoxDecoration( color: Colors.indigo, shape: BoxShape.circle, border: Border.all( width: 2, color: Colors.black54 ) ), child: Icon( Icons.thumb_up, size: 20, color: Colors.white, ), ), Expanded( child: Center( child: Text( 'Hello World!', style: TextStyle( fontSize: 30, color: Colors.indigo, fontWeight: FontWeight.bold ), ), ), ), Container( width: 50, height: 50, decoration: BoxDecoration( color: Colors.indigo, shape: BoxShape.circle, border: Border.all( width: 2, color: Colors.black54 ) ), child: Icon( Icons.thumb_up, size: 20, color: Colors.white, ), ), ], ),
Output
With Expanded

Without Expanded

Stack
Stack is also a multiple child widget which is similar to column but instead of laying out its children after each other, it allows overlapping them. You can achieve this by using the Positioned children which takes position attributes such as top, left, bottom, and right to control the relative position of its child.
See a more complex and creative Flutter Stack Widget Example to learn how to use better.
I know it might be a bit confusing to differentiate the purpose of Stack and Column widgets sometimes. So, make sure to understand what’s the difference between Stack and Column to use them efficiently in your apps
Example
Stack( children: [ Positioned( child: Container( width: 700, height: 200, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), border: Border.all( color: Colors.black26, width: 2 ) ), child: Image.asset('assets/hello-world.png', fit: BoxFit.contain), ), ), //profile Positioned( top: 100, left: 10, bottom: 10, child: Container( width: 80, height: 80, decoration: BoxDecoration( borderRadius: BorderRadius.circular(25), color: Colors.white70, image: DecorationImage( image: AssetImage('assets/logo.png'), fit: BoxFit.cover, ) ) ), ), ], )
Output

Conclusion
Now you know the introduction to Flutter layouts which you can use to build simple to complex UIs. Make sure to practice using all of them to understand the difference between them and identify the best situation to use each of them.