Một ứng dụng di động hiếm khi chỉ có một màn hình. Việc chuyển đổi từ màn hình Danh sách sang Chi tiết, hay từ Giỏ hàng sang Thanh toán được gọi là Navigation.
Trong Flutter, Navigation không chỉ đơn giản là push và pop. Nó là cả một nghệ thuật về quản lý ngăn xếp (Stack) và điều hướng theo URL (Deep Link).
| Phương pháp |
Độ khó |
Đặc điểm |
Khi nào dùng? |
| Navigator 1.0 |
Dễ |
Mệnh lệnh (Imperative) |
App đơn giản, ít màn hình |
| Navigator 2.0 |
Khó |
Khai báo (Declarative) |
App phức tạp, cần Deep Link |
| GoRouter |
Dễ |
Wrapper của Nav 2.0 |
Chuẩn mới của cộng đồng |
1. Cơ chế Stack: Vào trước, Ra sau (LIFO)
Nền tảng của Navigation trong Flutter là Stack. Hãy tưởng tượng nó giống như một chồng đĩa.
- Push: Đặt một màn hình mới lên đỉnh ngăn xếp (người dùng nhìn thấy màn hình này).
- Pop: Gỡ bỏ màn hình trên cùng, quay lại màn hình cũ.
// Chuyển sang màn hình mới
Navigator.push(context, MaterialPageRoute(builder: (context) => DetailsPage()));
// Quay lại màn hình cũ
Navigator.pop(context);
2. Truyền dữ liệu giữa các màn hình
Khi chuyển màn hình, bạn thường muốn mang theo “hành lý” (ví dụ: ID sản phẩm, tên User).

Cách 1: Truyền qua Constructor (Dễ nhất)
class DetailsPage extends StatelessWidget {
final int id;
// Nhận dữ liệu
const DetailsPage({required this.id});
}
// Gửi dữ liệu
Navigator.push(context,
MaterialPageRoute(builder: (context) => DetailsPage(id: 42))
);
Cách 2: Truyền qua Arguments (Dùng cho Named Route)
Navigator.pushNamed(context, '/details', arguments: {'id': 42});
3. Navigator 2.0 (Router): Tại sao lại khó?
Navigator 1.0 rất tuyệt, nhưng nó gặp vấn đề lớn với Web (URL Bar) và Deep Linking. Navigator 2.0 ra đời để giải quyết việc này bằng cách đồng bộ hóa trạng thái App với URL.

Thay vì gọi push, bạn thay đổi một biến trạng thái (ví dụ selectedBook), và Router sẽ tự động quyết định xem nên hiển thị màn hình nào. Tuy nhiên, API của nó rất phức tạp.
Lời khuyên: Đừng dùng Navigator 2.0 thuần. Hãy dùng package go_router. Nó đơn giản hóa mọi thứ:
// Định nghĩa router
final router = GoRouter(
routes: [
GoRoute(path: '/', builder: (context, state) => HomePage()),
GoRoute(path: '/details/:id', builder: (context, state) => DetailsPage(id: state.params['id'])),
],
);
// Sử dụng
context.go('/details/42');
Điều hướng đã xong. Bây giờ là lúc kết nối ứng dụng với thế giới bên ngoài. Làm sao để lấy dữ liệu từ Server về?
Bài tiếp theo: Kết nối API REST trong Flutter thực chiến (Http & Dio).
👉 Hướng dẫn gọi API và xử lý JSON trong Flutter
💡 Bạn muốn xây dựng App Thương mại điện tử với chức năng Giỏ hàng, Deep Link chuyên nghiệp?
Tất cả có trong dự án capstone của: Khóa học Lập trình Flutter Thực chiến