Ứng dụng thực tế có nhiều màn hình. Bài này dạy điều hướng bằng Navigator, truyền dữ liệu giữa màn hình, nhận kết quả trả về và định tuyến theo URL với go_router.
- Chuyển màn hình bằng Navigator.push/pop
- Truyền và nhận dữ liệu giữa màn hình
- Dùng go_router cho định tuyến khai báo
- Tạo thanh điều hướng dưới (NavigationBar)
- Route
- Một màn hình trong ngăn xếp điều hướng.
- Navigator stack
- Ngăn xếp màn hình: push thêm, pop bỏ.
- Deep link
- Liên kết mở thẳng một màn hình cụ thể.
- go_router
- Gói định tuyến chính thức theo URL.
Khái niệm và lý thuyết
Navigator quản lý màn hình như một ngăn xếp: push đặt màn hình mới lên trên, pop quay lại màn hình trước và có thể trả kết quả. Cách này đơn giản, phù hợp ứng dụng nhỏ.
Với ứng dụng có web, deep link hoặc nhiều tab, nên dùng định tuyến khai báo bằng gói go_router (do đội Flutter duy trì): mỗi màn hình gắn với một đường dẫn như /khoa-hoc/12, nút Back của trình duyệt và Android hoạt động đúng.
Navigator cơ bản
// Mở màn hình chi tiết, chờ kết quả
final daMua = await Navigator.push<bool>(
context,
MaterialPageRoute(builder: (_) => ChiTiet(id: 12)),
);
// Trong ChiTiet: trả kết quả và quay lại
Navigator.pop(context, true);go_router
flutter pub add go_routerfinal router = GoRouter(routes: [
GoRoute(path: '/', builder: (c, s) => const TrangChu(), routes: [
GoRoute(path: 'khoa-hoc/:id',
builder: (c, s) => ChiTiet(id: int.parse(s.pathParameters['id']!))),
]),
]);
// main: MaterialApp.router(routerConfig: router)
// Chuyển trang: context.go('/khoa-hoc/12'); quay lại: context.pop();Thanh điều hướng dưới
int _tab = 0;
Scaffold(
body: [const TrangChu(), const KhoaHoc(), const CaNhan()][_tab],
bottomNavigationBar: NavigationBar(
selectedIndex: _tab,
onDestinationSelected: (i) => setState(() => _tab = i),
destinations: const [
NavigationDestination(icon: Icon(Icons.home), label: 'Trang chủ'),
NavigationDestination(icon: Icon(Icons.book), label: 'Khóa học'),
NavigationDestination(icon: Icon(Icons.person), label: 'Cá nhân'),
],
),
);Với go_router, dùng StatefulShellRoute để mỗi tab giữ ngăn xếp riêng.
Đặt toàn bộ cấu hình route trong một tệp router.dart; khi ứng dụng lớn, thêm redirect để chặn màn hình yêu cầu đăng nhập.
Dùng context sau await để điều hướng có thể lỗi nếu màn hình đã đóng; kiểm tra context.mounted trước.
- Tạo danh sách khóa học, bấm vào mở màn hình chi tiết truyền id.
- Màn hình chi tiết có nút “Đăng ký”, trả về true; màn hình danh sách hiện SnackBar.
- Chuyển sang go_router với đường dẫn /khoa-hoc/:id, chạy trên Chrome thử nút Back.
- Thêm NavigationBar 3 tab.
- Navigator là ngăn xếp push/pop.
- Có thể truyền dữ liệu đi và nhận kết quả về.
- go_router: định tuyến theo URL, hỗ trợ web và deep link.
- NavigationBar cho bố cục nhiều tab.