In Flutter, layout is the core of building interfaces. No matter how complex an interface is, it's composed of basic layout widgets combined together. In this lesson, we'll detailedly explain the most commonly used layout widgets in Flutter, including linear layouts (Row/Column), stack layouts (Stack), and auxiliary layout widgets, helping you master the basic ability of building interfaces.
1. Linear Layouts: Row and Column
Linear layout is the most commonly used layout method, arranging child widgets in either horizontal direction (Row) or vertical direction (Column).
1. Row: Arrange Children Horizontally
The Row widget is used to arrange child widgets in the horizontal direction. Its simplified constructor is as follows:
Row({
Key? key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // Main axis alignment
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // Cross axis alignment
MainAxisSize mainAxisSize = MainAxisSize.max, // Main axis size (fill parent or wrap children)
VerticalDirection verticalDirection = VerticalDirection.down, // Vertical ordering
TextDirection? textDirection, // Horizontal ordering (affects start/end judgment)
List<Widget> children = const [], // List of child widgets
})
Example Code:
Row(
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 60, height: 60, color: Colors.green),
Container(width: 70, height: 70, color: Colors.blue),
],
)
When run, you'll see three colored blocks arranged horizontally in sequence.
2. Column: Arrange Children Vertically
Column is used exactly like Row, with the only difference being that it arranges child widgets in the vertical direction:
Column(
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 60, height: 60, color: Colors.green),
Container(width: 70, height: 70, color: Colors.blue),
],
)
3. Main Axis and Cross Axis
Understanding the main axis and cross axis is key to mastering linear layouts:
- Main axis: The direction in which widgets are arranged
- The main axis of Row is the horizontal direction (left-right)
- The main axis of Column is the vertical direction (top-bottom)
- Cross axis: The direction perpendicular to the main axis
- The cross axis of Row is the vertical direction (top-bottom)
- The cross axis of Column is the horizontal direction (left-right)
2. Alignment: MainAxisAlignment and CrossAxisAlignment
Alignment allows precise control of the position of child widgets on the main and cross axes.
1. Main Axis Alignment (MainAxisAlignment)
Controls how child widgets are arranged along the main axis. Common values include:
- start: Align along the start of the main axis (left for Row, top for Column)
- end: Align along the end of the main axis (right for Row, bottom for Column)
- center: Center alignment on the main axis
- spaceBetween: Evenly distribute space between children (with end children touching edges)
- spaceAround: Evenly distribute space around children (space at ends is half of middle spaces)
- spaceEvenly: Evenly distribute all space (including at ends)
Example (Row + spaceBetween):
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
)
2. Cross Axis Alignment (CrossAxisAlignment)
Controls how child widgets are arranged along the cross axis. Common values include:
- start: Align along the start of the cross axis
- end: Align along the end of the cross axis
- center: Center alignment on the cross axis (default value)
- stretch: Stretch children to fill the cross axis (requires children to have no fixed size)
- baseline: Align by baseline (only effective for Row, related to text baseline)
Example (Row + stretch):
Row(
crossAxisAlignment: CrossAxisAlignment.stretch, // Stretch vertically
children: [
Container(width: 50, color: Colors.red), // No height specified, will be stretched
Container(width: 50, height: 60, color: Colors.green),
Container(width: 50, height: 70, color: Colors.blue),
],
)
3. Stack Layout: Stack and Positioned
When you need child widgets to display in a stack (such as text over an image), use the combination of Stack and Positioned.
1. Stack: Stacking Child Widgets
Stack stacks child widgets in order (later added widgets appear on top). Its simplified constructor is as follows:
Stack({
Key? key,
AlignmentGeometry alignment = Alignment.center, // Alignment for unpositioned children
TextDirection? textDirection,
StackFit fit = StackFit.loose, // How children fit into the stack
Clip clipBehavior = Clip.hardEdge, // Whether to clip content outside bounds
List<Widget> children = const [],
})
Basic Example:
Stack(
children: [
// Bottom red container
Container(width: 200, height: 200, color: Colors.red),
// Middle green container (on top of red)
Container(width: 150, height: 150, color: Colors.green),
// Top blue container (on top of all)
Container(width: 100, height: 100, color: Colors.blue),
],
)
2. Positioned: Positioning Child Widgets
Positioned is used to precisely position child widgets within a Stack and must be a direct child of Stack. Common properties:
- left: Distance from the left edge of the Stack
- right: Distance from the right edge of the Stack
- top: Distance from the top edge of the Stack
- bottom: Distance from the bottom edge of the Stack
- width/height: Specify the width and height of the child widget (optional)
Example:
Stack(
children: [
Container(width: 200, height: 200, color: Colors.grey),
// Positioned at top-left
Positioned(
left: 10,
top: 10,
child: Container(width: 50, height: 50, color: Colors.red),
),
// Positioned at bottom-right
Positioned(
right: 10,
bottom: 10,
child: Container(width: 50, height: 50, color: Colors.blue),
),
],
)
4. Common Layout Auxiliary Widgets
These widgets don't handle layout themselves but help adjust the position, size, etc., of child widgets.
1. Padding: Inner Spacing
Adds inner padding to a child widget (distance between child and parent container edges):
Padding(
padding: EdgeInsets.all(16), // Add 16px padding to all four directions
// Can also set individually: EdgeInsets.only(left: 10, top: 20)
child: Container(width: 100, height: 100, color: Colors.red),
)
Common EdgeInsets constructors:
- all(value): Uniform value for all sides
- only(left, top, right, bottom): Set individual sides
- symmetric(horizontal, vertical): Symmetric horizontal/vertical settings
2. Margin: Outer Spacing
There's no separate Margin widget in Flutter. It's implemented through the margin property of Container (distance between child and other widgets):
Container(
margin: EdgeInsets.all(10), // Outer margin
padding: EdgeInsets.all(10), // Inner padding
color: Colors.grey,
child: Container(width: 50, height: 50, color: Colors.red),
)
3. Center: Center Alignment
A simplified alignment widget, equivalent to Align(alignment: Alignment.center, child: ...):
Center(
child: Container(width: 100, height: 100, color: Colors.green),
)
4. Expanded: Fill Remaining Space
In Row or Column, Expanded makes the child widget fill the remaining space in the main axis direction, solving the problem of child widgets' total width/height exceeding the parent widget (overflow shows yellow line errors).
Basic Usage:
Row(
children: [
Container(width: 50, height: 50, color: Colors.red),
Expanded( // Fills remaining space
child: Container(height: 50, color: Colors.green),
),
Container(width: 50, height: 50, color: Colors.blue),
],
)
Proportional Allocation (flex):
Row(
children: [
Expanded(
flex: 1, // Takes 1 part
child: Container(height: 50, color: Colors.red),
),
Expanded(
flex: 2, // Takes 2 parts (total space divided into 3 parts)
child: Container(height: 50, color: Colors.green),
),
],
)
5. Comprehensive Example: Combined Layout
In actual development, layout widgets are usually used nested. Here's a simple user information card example:
Container(
width: 300,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 3)],
),
child: Row( // Arrange avatar and info horizontally
children: [
// Avatar
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(30),
),
),
SizedBox(width: 12), // Spacing
// Info area (arranged vertically)
Expanded( // Fills remaining width
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // Left-aligned
children: [
Text("Zhang San", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 4),
Text("Flutter Developer", style: TextStyle(color: Colors.grey)),
],
),
),
// Right arrow
Icon(Icons.arrow_right, color: Colors.grey),
],
),
)
Top comments (0)