Skip to Content

Row và Column trong Flutter

1. Giới thiệu

RowColumn là hai widget layout cơ bản nhất:

  • Row → Sắp xếp children theo chiều ngang
  • Column → 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)
endCuối trục
centerGiữa trục
spaceBetweenKhoảng cách đều, không có ở đầu/cuối
spaceAroundKhoảng cách đều, nửa ở đầu/cuối
spaceEvenlyKhoả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ụ
endCuối trục phụ
centerGiữa trục phụ (mặc định)
stretchKéo dãn full chiều
baselineCăn theo baseline (chỉ Row)

6. MainAxisSize

Row( mainAxisSize: MainAxisSize.min, // Co lại vừa children children: [...], )
Giá trịMô tả
maxChiếm hết không gian có sẵn (mặc định)
minCo 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ế

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/PropertyMục đích
RowLayout ngang
ColumnLayout dọc
mainAxisAlignmentCăn chỉnh trục chính
crossAxisAlignmentCăn chỉnh trục phụ
mainAxisSizeKích thước trục chính
ExpandedChiếm không gian còn lại
SizedBoxTạo khoảng cách
Last updated on