When building beautiful and functional UIs in Flutter, arranging widgets is one of the most essential tasks. Sometimes we want widgets arranged vertically (that’s where the Column widget comes in), and sometimes we want them arranged horizontally. For horizontal layouts, Flutter provides a powerful widget: the Row.
In this deep dive, we’ll cover everything about the Row widget, including its purpose, properties, alignment options, real-world use cases, and best practices. By the end, you’ll be able to confidently use Row in almost any UI design.
Introduction to Row
The Row widget in Flutter is a layout widget that arranges its children horizontally in a single line.
- Every child is placed side by side, from left to right (or right to left in RTL languages).
- It is extremely flexible, allowing alignment and distribution of children with the help of properties like:
mainAxisAlignment→ Controls horizontal alignment.crossAxisAlignment→ Controls vertical alignment.
Why Do We Need the Row Widget?
Almost every app requires a horizontal arrangement at some point. Examples include:
- A toolbar with icons (e.g., home, search, profile).
- A row of buttons for actions.
- A card with an image on the left and text on the right.
- A form field with a label on the left and input field on the right.
Without Row, creating these layouts would be unnecessarily complex.
Basic Syntax of Row
Row(
children: <Widget>[
Widget1(),
Widget2(),
Widget3(),
],
)
- The
childrenproperty accepts a list of widgets. - Each widget is placed side by side in the order they appear.
Example: Simple Row
Row(
children: [
Icon(Icons.home),
SizedBox(width: 10),
Icon(Icons.search),
SizedBox(width: 10),
Icon(Icons.person),
],
)
This will display three icons in a row: Home, Search, Profile, with spacing in between.
Understanding the Main Axis and Cross Axis
To master Row, we must understand axis concepts:
- Main Axis (Horizontal) → The primary direction in which Row lays out its children.
- Cross Axis (Vertical) → The perpendicular direction to the main axis.
In simple terms:
- In Row → Main Axis = Horizontal, Cross Axis = Vertical.
- In Column → Main Axis = Vertical, Cross Axis = Horizontal.
The mainAxisAlignment Property
This property controls how children are aligned horizontally along the main axis.
Options:
- start → Aligns children to the left (default).
- end → Aligns children to the right.
- center → Centers children horizontally.
- spaceBetween → Distributes children evenly, with space only between them.
- spaceAround → Equal space around each child.
- spaceEvenly → Equal space between all children and edges.
Example
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(Icons.home),
Icon(Icons.search),
Icon(Icons.person),
],
)
Result: Icons are evenly spaced across the row.
The crossAxisAlignment Property
This property controls how children are aligned vertically along the cross axis.
Options:
- start → Aligns children to the top.
- end → Aligns children to the bottom.
- center → Aligns children to the vertical center (default).
- stretch → Expands children to fill the height of the row.
- baseline → Aligns children according to text baselines.
Example
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.home, size: 30),
Text("Home", style: TextStyle(fontSize: 24)),
],
)
Result: The icon and text align at the top of the Row.
Combining MainAxisAlignment and CrossAxisAlignment
You can combine both properties for precise control.
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Icon(Icons.star, size: 40),
Text("Favorite", style: TextStyle(fontSize: 20)),
],
)
Here:
- Children are horizontally centered.
- Vertically aligned at the bottom.
Example Use Case: Toolbar with Icons
A common use case of Row is building a toolbar with multiple icons.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.menu),
Text("My App", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
Icon(Icons.notifications),
],
)
Result:
- Menu icon on the left.
- App title in the center.
- Notification icon on the right.
This mimics a basic app bar layout.
Handling Overflow in Row
By default, Row does not scroll. If children exceed available width, you get an overflow error.
Solutions:
- Wrap with SingleChildScrollView
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(20, (index) => Text("Item $index")),
),
)
- Use Wrap Widget → Automatically wraps to the next line.
Expanded and Flexible with Row
Often, you want children inside a Row to take available space proportionally.
Example with Expanded
Row(
children: [
Expanded(child: Container(color: Colors.red, height: 50)),
Expanded(child: Container(color: Colors.blue, height: 50)),
],
)
Result: Both containers take equal width.
Example with Flexible
Row(
children: [
Flexible(flex: 2, child: Container(color: Colors.green, height: 50)),
Flexible(flex: 1, child: Container(color: Colors.orange, height: 50)),
],
)
Result: Green box takes 2/3 of space, orange takes 1/3.
Real-World Examples of Row
1. Buttons Row
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(onPressed: () {}, child: Text("Accept")),
ElevatedButton(onPressed: () {}, child: Text("Decline")),
],
)
2. Profile Layout
Row(
children: [
CircleAvatar(radius: 30, backgroundImage: AssetImage("profile.jpg")),
SizedBox(width: 10),
Text("John Doe", style: TextStyle(fontSize: 18)),
],
)
Performance of Row
- Row is lightweight and renders quickly.
- But beware of too many children → it can cause overflow.
- Use ListView for large horizontal lists instead.
Best Practices for Using Row
- Use
ExpandedorFlexiblefor responsive layouts. - Always check for overflow on small screens.
- Combine with Column for grid-like layouts.
- Use alignment properties instead of padding hacks.
- For scrollable horizontal layouts, wrap Row in SingleChildScrollView.
Common Mistakes with Row
- Forgetting to handle overflow → leads to ugly yellow/black stripes.
- Using too many
SizedBoxwidgets instead ofMainAxisAlignment. - Putting complex layouts in a Row without wrapping → causes rendering issues.
- Ignoring text baseline alignment → makes text look misaligned.
Advanced Usage of Row
Row inside Column (Nested Layouts)
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text("Name"), Text("John")],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text("Email"), Text("[email protected]")],
),
],
)
This is great for displaying structured data.
Row vs Column
| Feature | Row (Horizontal) | Column (Vertical) |
|---|---|---|
| Main Axis | Horizontal (left to right) | Vertical (top to bottom) |
| Cross Axis | Vertical (top to bottom) | Horizontal (left to right) |
| Common Use Case | Toolbars, button groups | Forms, lists, stacked items |
Leave a Reply