Row và Column trong Flutter
1. Giới thiệu
Row và Column là hai widget layout cơ bản nhất:
Row→ Sắp xếp children theo chiều ngangColumn→ Sắp xếp children theo chiều dọc
// Hàng ngang
Row(
children: [Widget1(), Widget2(), Widget3()],
)
// Cột dọc
Column(
children: [Widget1(), Widget2(), Widget3()],
)Main Axis vs Cross Axis
Hiểu về trục chính (Main) và trục phụ (Cross) là chìa khóa để mastering layout:
ROW (Hàng Ngang) COLUMN (Cột Dọc)
Cross Axis (Vertical) Main Axis (Vertical)
↑ ↑
│ │
Main ───┼───▶ Axis (Horizontal) Cross ──┼──▶ Axis (Horizontal)
│ │
↓ ↓- Row:
- Main Axis: Nằm ngang (→)
- Cross Axis: Nằm dọc (↓)
- Column:
- Main Axis: Nằm dọc (↓)
- Cross Axis: Nằm ngang (→)
2. Row cơ bản
Row(
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),
],
)3. Column cơ bản
Column(
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),
],
)4. MainAxisAlignment
Căn chỉnh theo trục chính (ngang cho Row, dọc cho Column):
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [...],
)| Giá trị | Mô tả |
|---|---|
start | Đầu trục (mặc định) |
end | Cuối trục |
center | Giữa trục |
spaceBetween | Khoảng cách đều, không có ở đầu/cuối |
spaceAround | Khoảng cách đều, nửa ở đầu/cuối |
spaceEvenly | Khoảng cách đều hoàn toàn |
5. CrossAxisAlignment
Căn chỉnh theo trục phụ (dọc cho Row, ngang cho Column):
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [...],
)| Giá trị | Mô tả |
|---|---|
start | Đầu trục phụ |
end | Cuối trục phụ |
center | Giữa trục phụ (mặc định) |
stretch | Kéo dãn full chiều |
baseline | Căn theo baseline (chỉ Row) |
6. MainAxisSize
Row(
mainAxisSize: MainAxisSize.min, // Co lại vừa children
children: [...],
)| Giá trị | Mô tả |
|---|---|
max | Chiếm hết không gian có sẵn (mặc định) |
min | Co lại vừa children |
7. Spacing với SizedBox
Row(
children: [
Text('Item 1'),
SizedBox(width: 16), // Khoảng cách ngang
Text('Item 2'),
SizedBox(width: 16),
Text('Item 3'),
],
)
Column(
children: [
Text('Item 1'),
SizedBox(height: 16), // Khoảng cách dọc
Text('Item 2'),
],
)8. Expanded và Flexible
Expanded
Chiếm hết không gian còn lại:
Row(
children: [
Container(width: 50, height: 50, color: Colors.red),
Expanded(
child: Container(height: 50, color: Colors.green), // Chiếm hết
),
Container(width: 50, height: 50, color: Colors.blue),
],
)Flex factor
Row(
children: [
Expanded(
flex: 1, // 1 phần
child: Container(height: 50, color: Colors.red),
),
Expanded(
flex: 2, // 2 phần
child: Container(height: 50, color: Colors.green),
),
],
)9. Ví dụ thực tế
Navigation Bar
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.menu),
Text('Title', style: TextStyle(fontSize: 18)),
Icon(Icons.search),
],
)Form Layout
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Username', style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
TextField(),
SizedBox(height: 16),
Text('Password', style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
TextField(obscureText: true),
SizedBox(height: 24),
ElevatedButton(
onPressed: () {},
child: Text('Login'),
),
],
)Profile Header
Row(
children: [
CircleAvatar(radius: 30, backgroundImage: NetworkImage('...')),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('John Doe', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
Text('john@email.com', style: TextStyle(color: Colors.grey)),
],
),
),
IconButton(icon: Icon(Icons.edit), onPressed: () {}),
],
)10. Lỗi thường gặp
Row/Column overflow
// ❌ Lỗi overflow
Row(
children: [
Text('Very very very very long text...'),
],
)
// ✅ Fix với Expanded hoặc Flexible
Row(
children: [
Expanded(
child: Text('Very very long text...', overflow: TextOverflow.ellipsis),
),
],
)📝 Tóm tắt
| Widget/Property | Mục đích |
|---|---|
Row | Layout ngang |
Column | Layout dọc |
mainAxisAlignment | Căn chỉnh trục chính |
crossAxisAlignment | Căn chỉnh trục phụ |
mainAxisSize | Kích thước trục chính |
Expanded | Chiếm không gian còn lại |
SizedBox | Tạo khoảng cách |
Last updated on