Row and Column in Flutter
Master the fundamental widgets for organizing your user interface
Download Complete ExamplesWhat are Row and Column?
Row and Column are the most important widgets in Flutter for organizing other widgets on the screen. They are flex layout widgets that arrange their children in a specific direction.
Row
Organizes widgets horizontally from left to right
Column
Organizes widgets vertically from top to bottom
Basic Syntax
Row Basics
Row(
children: [
Text('Element 1'),
Text('Element 2'),
Text('Element 3'),
],
)
Column Basics
Column(
children: [
Text('Element 1'),
Text('Element 2'),
Text('Element 3'),
],
)
Main Properties
mainAxisAlignment
Alignment on the main axis
crossAxisAlignment
Alignment on the cross axis
mainAxisSize
Size on the main axis
mainAxisAlignment
Controls how widgets are distributed along the main axis (horizontal for Row, vertical for Column).
Examples in Row:
MainAxisAlignment.start
MainAxisAlignment.center
MainAxisAlignment.spaceBetween
Código de Ejemplo:
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),
],
)
crossAxisAlignment
Controls how widgets are aligned on the cross axis (vertical for Row, horizontal for Column).
Examples in Column:
CrossAxisAlignment.start
CrossAxisAlignment.center
CrossAxisAlignment.stretch
Practical Examples
1. Top Navigation Bar
Row(
children: [
IconButton(icon: Icon(Icons.menu), onPressed: () {}),
Expanded(
child: Text('Mi Aplicación', textAlign: TextAlign.center),
),
IconButton(icon: Icon(Icons.search), onPressed: () {}),
IconButton(icon: Icon(Icons.settings), onPressed: () {}),
],
)
2. Profile Card
Row(
children: [
CircleAvatar(backgroundImage: NetworkImage(url)),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Juan Pérez', style: TextStyle(fontWeight: FontWeight.bold)),
Text('juan@email.com'),
],
),
),
Icon(Icons.chevron_right),
],
)
3. Login Form
Column(
children: [
TextField(decoration: InputDecoration(labelText: 'Email')),
SizedBox(height: 16),
TextField(decoration: InputDecoration(labelText: 'Password'), obscureText: true),
SizedBox(height: 24),
Row(
children: [
Expanded(child: TextButton(child: Text('Cancel'), onPressed: () {})),
SizedBox(width: 16),
Expanded(child: ElevatedButton(child: Text('Log In'), onPressed: () {})),
],
),
],
)
Tester for Row and Column
// El código se generará aquí
Row vs Column - When to use each one?
| Aspect | Row | Column |
|---|---|---|
| Address | Horizontal | Vertical |
| Main Axis | Horizontal | Vertical |
| Cross Axis | Vertical | Horizontal |
| Use Cases | Navigation bars, data rows, inline buttons | Forms, lists, vertically scrolling pages |
| Example | Icon + Text + Button | Title + Image + Description + Button |
Special Child Widgets
Common Errors and Solutions
❌ "Vertical viewport was given unbounded height"
Problem: A Column inside a ListView without a defined height
Solution: Use SingleChildScrollView or wrap in Expanded
// MALListView(children: [Column(children: [...]))])
// BIENSingleChildScrollView(child: Column(children: [...]))
❌ "RenderFlex overflowed by ... pixels"
Problem: The widgets don't fit on the screen
Solution: Use SingleChildScrollView or reduce the content
// MALColumn(children: [/* mucho contenido */])
// BIENSingleChildScrollView(child: Column(children: [...]))
❌ Widgets don't align correctly
Problem: crossAxisAlignment misconfigured
Solution: Use CrossAxisAlignment.stretch or define widths
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(height: 50, color: Colors.red),
Container(height: 50, color: Colors.blue),
],
)
Tips and Best Practices
🎯 Use SizedBox for spacing
Instead of Padding to separate widgets, use SizedBox, which is more efficient:
Column(
children: [
Text('Title'),
SizedBox(height: 16), // Mejor que Padding Text('Subtitle'),
],
)
📱 Considera responsive design
Use LayoutBuilder or MediaQuery to adapt Row/Column to different screen sizes:
LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 600) {
return Row(children: [...]); // Tablet
} else {
return Column(children: [...]); // Móvil }
},
)
⚡ Optimize with const
Use const constructors for widgets that don't change:
Column(
children: const [
Text('Title'),
SizedBox(height: 16),
Text('Subtitle'),
],
)
Exercises to Practice
Exercise 1: Toolbar
Create a toolbar with centered icons and space between them.
Hint: Use Row with MainAxisAlignment.spaceEvenly
Exercise 2: Registration Form
Create a form with fields stacked vertically and buttons aligned to the right.
Hint: Combine Column and Row with CrossAxisAlignment.end
Exercise 3: Product Card
Create a card with an image on the left and text on the right that takes up the remaining space.
Hint: Use Row with Expanded around the text