Flutter Layout Basics
Layout is a core concept in Flutter UI development.
This section will introduce the most commonly used layout widgets, including Row, Column, Stack, Flex, etc.
Layout Widget Overview
Flutter provides a rich set of layout widgets that can meet various interface design needs.
| Widget | Purpose |
|---|---|
| Row | Arrange Child Widgets Horizontally |
| Column | Arrange Child Widgets Vertically |
| Stack | Stack Child Widgets |
| Flex | Flexible linear layout (base class for Row/Column) |
| GridView | Grid layout |
| ListView | List layout |
Row - Horizontal Layout
Row is used to arrange child widgets in the horizontal direction.
Example: Row Basic Usage
// Arrange three icons horizontally
Row(
children: [
Icon(Icons.home, color: Colors.blue),
Icon(Icons.search, color: Colors.green),
Icon(Icons.settings, color: Colors.grey),
],
)
// Row with spacing
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // Main axis alignment
children: [
Icon(Icons.home, color: Colors.blue),
Icon(Icons.search, color: Colors.green),
Icon(Icons.settings, color: Colors.grey),
],
)
Row(
children: [
Icon(Icons.home, color: Colors.blue),
Icon(Icons.search, color: Colors.green),
Icon(Icons.settings, color: Colors.grey),
],
)
// Row with spacing
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // Main axis alignment
children: [
Icon(Icons.home, color: Colors.blue),
Icon(Icons.search, color: Colors.green),
Icon(Icons.settings, color: Colors.grey),
],
)
mainAxisAlignment - Main axis alignment
| Value | Description |
|---|---|
| MainAxisAlignment.start | Left-aligned (default) |
| MainAxisAlignment.center | Center align |
| MainAxisAlignment.end | Right-aligned |
| MainAxisAlignment.spaceBetween | Space between, equal spacing between items |
| MainAxisAlignment.spaceEvenly | Equal spacing between items and at both ends |
| MainAxisAlignment.spaceAround | Equal spacing between items, greater than spacing at ends |
Column - Vertical Layout
Column is used to arrange child widgets in the vertical direction.
Example: Column Basic Usage
// Arrange three texts vertically
Column(
children: [
Text('First line', style: TextStyle(fontSize: 20)),
Text('Second line', style: TextStyle(fontSize: 20)),
Text('Third line', style: TextStyle(fontSize: 20)),
],
)
// Column with spacing and alignment
Column(
mainAxisAlignment: MainAxisAlignment.center, // Vertically centered
crossAxisAlignment: CrossAxisAlignment.start, // Horizontally left-aligned
children: [
Text('Title', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text('content content content'),
const SizedBox(height: 8),
Text('Bottom description'),
],
)
Column(
children: [
Text('First line', style: TextStyle(fontSize: 20)),
Text('Second line', style: TextStyle(fontSize: 20)),
Text('Third line', style: TextStyle(fontSize: 20)),
],
)
// Column with spacing and alignment
Column(
mainAxisAlignment: MainAxisAlignment.center, // Vertically centered
crossAxisAlignment: CrossAxisAlignment.start, // Horizontally left-aligned
children: [
Text('Title', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text('content content content'),
const SizedBox(height: 8),
Text('Bottom description'),
],
)
crossAxisAlignment - cross-axis alignment
| Value | Description |
|---|---|
| CrossAxisAlignment.start | Align top/left |
| CrossAxisAlignment.center | Center align |
| CrossAxisAlignment.end | Align bottom/right |
| CrossAxisAlignment.stretch | Stretch to fill parent container |
Expanded and Flexible
Expanded and Flexible are used to make child widgets fill the remaining space.
Example: Expanded Usage
// Fixed width + adaptive width
Row(
children: [
// Fixed width 100
Container(width: 100, height: 50, color: Colors.red),
// Occupy remaining space
Expanded(
child: Container(height: 50, color: Colors.green),
),
// Fixed width 50
Container(width: 50, height: 50, color: Colors.blue),
],
)
// Distribution ratio
Row(
children: [
// Occupy 1 part
Expanded(
flex: 1,
child: Container(height: 50, color: Colors.red),
),
// Occupy 2 parts
Expanded(
flex: 2,
child: Container(height: 50, color: Colors.green),
),
// Occupy 1 part
Expanded(
flex: 1,
child: Container(height: 50, color: Colors.blue),
),
],
)
Row(
children: [
// Fixed width 100
Container(width: 100, height: 50, color: Colors.red),
// Occupy remaining space
Expanded(
child: Container(height: 50, color: Colors.green),
),
// Fixed width 50
Container(width: 50, height: 50, color: Colors.blue),
],
)
// Distribution ratio
Row(
children: [
// Occupy 1 part
Expanded(
flex: 1,
child: Container(height: 50, color: Colors.red),
),
// Occupy 2 parts
Expanded(
flex: 2,
child: Container(height: 50, color: Colors.green),
),
// Occupy 1 part
Expanded(
flex: 1,
child: Container(height: 50, color: Colors.blue),
),
],
)
Stack - Stacked Layout
Stack is used to stack child widgets together, often used to achieve effects such as floating elements and layer overlays.
Example: Stack Usage
// Basic Stack
Stack(
children: [
// Bottom layer: background image
Container(
width: 200,
height: 200,
color: Colors.blue,
),
// Middle layer: semi-transparent overlay
Container(
width: 180,
height: 180,
color: Colors.white.withOpacity(0.5),
),
// Top layer: text
const Center(
child: Text(
'Overlay content',
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
],
)
// Stack with positioning
Stack(
children: [
Container(color: Colors.grey[300]),
// Positioned to top-right corner
Positioned(
right: 10,
top: 10,
child: Icon(Icons.close, color: Colors.red),
),
// Positioned to bottom-left corner
Positioned(
left: 10,
bottom: 10,
child: Text('Bottom-left text'),
),
],
)
Stack(
children: [
// Bottom layer: background image
Container(
width: 200,
height: 200,
color: Colors.blue,
),
// Middle layer: semi-transparent overlay
Container(
width: 180,
height: 180,
color: Colors.white.withOpacity(0.5),
),
// Top layer: text
const Center(
child: Text(
'Overlay content',
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
],
)
// Stack with positioning
Stack(
children: [
Container(color: Colors.grey[300]),
// Positioned to top-right corner
Positioned(
right: 10,
top: 10,
child: Icon(Icons.close, color: Colors.red),
),
// Positioned to bottom-left corner
Positioned(
left: 10,
bottom: 10,
child: Text('Bottom-left text'),
),
],
)
Padding and Margin
Use Padding and Margin to control the padding and margin of elements.
Example: Padding and Margin
// Use Padding to set padding
Padding(
padding: const EdgeInsets.all(16.0), // All four sides 16 pixels
child: Text('Text with padding'),
)
// Set each side separately
Padding(
padding: EdgeInsets.only(
left: 10,
right: 20,
top: 5,
bottom: 5,
),
child: Text('Custom padding'),
)
// Use EdgeInsets.symmetric for symmetric padding
Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text('Horizontal 16, vertical 8'),
)
// Container combining margin and padding
Container(
margin: const EdgeInsets.all(10), // Outer margin
padding: const EdgeInsets.all(16), // Inner padding
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: BorderRadius.circular(8),
),
child: Text('Container content'),
)
Padding(
padding: const EdgeInsets.all(16.0), // All four sides 16 pixels
child: Text('Text with padding'),
)
// Set each side separately
Padding(
padding: EdgeInsets.only(
left: 10,
right: 20,
top: 5,
bottom: 5,
),
child: Text('Custom padding'),
)
// Use EdgeInsets.symmetric for symmetric padding
Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text('Horizontal 16, vertical 8'),
)
// Container combining margin and padding
Container(
margin: const EdgeInsets.all(10), // Outer margin
padding: const EdgeInsets.all(16), // Inner padding
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: BorderRadius.circular(8),
),
child: Text('Container content'),
)
Scaffold and AppBar
Scaffold provides the basic page structure of Material Design, AppBar is the top app bar.
Example: Basic Scaffold Structure
// Material Design page scaffold
Scaffold(
// Top app bar
appBar: AppBar(
title: const Text('My App'),
backgroundColor: Colors.blue,
elevation: 4, // Shadow depth
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {},
),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {},
),
],
),
// Page body
body: const Center(
child: Text('page body content'),
),
// Floating action button
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
// Bottom navigation bar
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'My'),
],
),
)
Scaffold(
// Top app bar
appBar: AppBar(
title: const Text('My App'),
backgroundColor: Colors.blue,
elevation: 4, // Shadow depth
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {},
),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {},
),
],
),
// Page body
body: const Center(
child: Text('page body content'),
),
// Floating action button
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
// Bottom navigation bar
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'My'),
],
),
)