↔️ Row & Column
1. Giới thiệu
Phần tiêu đề “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 ngangRow( children: [Widget1(), Widget2(), Widget3()],)
// Cột dọcColumn( children: [Widget1(), Widget2(), Widget3()],)Main Axis vs Cross Axis
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “8. Expanded và Flexible”Expanded
Phần tiêu đề “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
Phần tiêu đề “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ế
Phần tiêu đề “9. Ví dụ thực tế”Navigation Bar
Phần tiêu đề “Navigation Bar”Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Icon(Icons.menu), Text('Title', style: TextStyle(fontSize: 18)), Icon(Icons.search), ],)Form Layout
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “10. Lỗi thường gặp”Row/Column overflow
Phần tiêu đề “Row/Column overflow”// ❌ Lỗi overflowRow( children: [ Text('Very very very very long text...'), ],)
// ✅ Fix với Expanded hoặc FlexibleRow( children: [ Expanded( child: Text('Very very long text...', overflow: TextOverflow.ellipsis), ), ],)📝 Tóm tắt
Phần tiêu đề “📝 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 |