🚀 Navigation cơ bản
1. Navigator là gì?
Phần tiêu đề “1. Navigator là gì?”Flutter sử dụng Navigator để quản lý stack các routes (screens):
┌─────────────┐│ Screen C │ ← Top of stack (visible)├─────────────┤│ Screen B │├─────────────┤│ Screen A │ ← Bottom of stack└─────────────┘2. Navigator.push
Phần tiêu đề “2. Navigator.push”Thêm screen mới lên stack:
Navigator.push( context, MaterialPageRoute( builder: (context) => SecondScreen(), ),);Shorthand:
Navigator.of(context).push( MaterialPageRoute(builder: (_) => SecondScreen()),);3. Navigator.pop
Phần tiêu đề “3. Navigator.pop”Quay lại screen trước:
Navigator.pop(context);Hoặc:
Navigator.of(context).pop();4. Ví dụ đầy đủ
Phần tiêu đề “4. Ví dụ đầy đủ”Screen 1
Phần tiêu đề “Screen 1”class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('First Screen')), body: Center( child: ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => SecondScreen()), ); }, child: Text('Go to Second'), ), ), ); }}Screen 2
Phần tiêu đề “Screen 2”class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Second Screen')), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('Go Back'), ), ), ); }}5. pushReplacement
Phần tiêu đề “5. pushReplacement”Thay thế screen hiện tại (không thể back):
Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => HomeScreen()),);Use case: Sau khi login, replace LoginScreen bằng HomeScreen.
6. pushAndRemoveUntil
Phần tiêu đề “6. pushAndRemoveUntil”Push screen mới và xóa các screens trước đó:
// Xóa tất cả và push HomeNavigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (_) => HomeScreen()), (route) => false, // Xóa tất cả);
// Xóa đến khi gặp route có tên '/home'Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (_) => ProfileScreen()), ModalRoute.withName('/home'),);Use case: Logout - clear stack và về LoginScreen.
7. popUntil
Phần tiêu đề “7. popUntil”Pop về screen cụ thể:
// Pop về screen đầu tiênNavigator.popUntil(context, (route) => route.isFirst);
// Pop về named routeNavigator.popUntil(context, ModalRoute.withName('/home'));8. canPop và maybePop
Phần tiêu đề “8. canPop và maybePop”Kiểm tra có thể pop không:
if (Navigator.canPop(context)) { Navigator.pop(context);}
// HoặcNavigator.maybePop(context); // Pop nếu có thể9. WillPopScope - Handle back button
Phần tiêu đề “9. WillPopScope - Handle back button”WillPopScope( onWillPop: () async { // Return true để pop, false để không final shouldPop = await showDialog<bool>( context: context, builder: (context) => AlertDialog( title: Text('Exit?'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: Text('No'), ), TextButton( onPressed: () => Navigator.pop(context, true), child: Text('Yes'), ), ], ), ); return shouldPop ?? false; }, child: Scaffold(...),)Flutter 3.12+: Dùng
PopScopethay choWillPopScope
PopScope( canPop: false, onPopInvoked: (didPop) async { if (didPop) return; // Show confirmation dialog }, child: Scaffold(...),)10. PageRouteBuilder - Custom Transition
Phần tiêu đề “10. PageRouteBuilder - Custom Transition”Navigator.push( context, PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => SecondScreen(), transitionsBuilder: (context, animation, secondaryAnimation, child) { // Fade transition return FadeTransition(opacity: animation, child: child);
// Slide transition // return SlideTransition( // position: Tween<Offset>( // begin: Offset(1.0, 0.0), // end: Offset.zero, // ).animate(animation), // child: child, // ); }, ),);📝 Tóm tắt
Phần tiêu đề “📝 Tóm tắt”| Method | Mô tả |
|---|---|
push |
Thêm screen vào stack |
pop |
Quay lại screen trước |
pushReplacement |
Thay thế screen hiện tại |
pushAndRemoveUntil |
Push và xóa các screens |
popUntil |
Pop về screen cụ thể |
canPop |
Kiểm tra có thể pop |
maybePop |
Pop nếu có thể |