نمونه ای که خودم نوشتم با متد popscop
import 'package:flutter/material.dart';
import 'package:nikestore/screens/home/home.dart';
import 'package:nikestore/screens/product/productScreen.dart';
import 'package:nikestore/screens/profile/profileScreen.dart';
const int homeIndex = 0;
const int product = 1;
const int profileIndex = 2;
final homeNavigatorKey = GlobalKey<NavigatorState>();
final productNavigatorKey = GlobalKey<NavigatorState>();
final profileNavigatorKey = GlobalKey<NavigatorState>();
class RootScreen extends StatefulWidget {
const RootScreen({super.key});
@override
State<RootScreen> createState() => _RootScreenState();
}
class _RootScreenState extends State<RootScreen> {
int selectedScreenIndex = homeIndex;
late List<int> navigationStack = [homeIndex];
// Future<bool> onWillPop() async {
// // If there's more than one screen in the stack, pop back to the previous one
// if (navigationStack.length > 1) {
// navigationStack.removeLast(); // Remove current screen
// setState(() {
// selectedScreenIndex = navigationStack.last; // Go to previous screen
// });
// return false; // Prevents pop
// }
// // If only one screen (home), then exit the app
// return true; // Allows pop
// }
Future<bool> onWillPop() async {
final currentNavigator = switch (selectedScreenIndex) {
homeIndex => homeNavigatorKey.currentState,
product => productNavigatorKey.currentState,
profileIndex => profileNavigatorKey.currentState,
_ => null,
};
if (currentNavigator != null &&
currentNavigator.canPop()) {
currentNavigator.pop();
return false;
}
if (navigationStack.length > 1) {
navigationStack.removeLast();
setState(() {
selectedScreenIndex = navigationStack.last;
});
return false;
}
return true;
}
void navigateToScreen(int screenIndex) {
setState(() {
selectedScreenIndex = screenIndex;
// If the screen is already in the stack, don't add it again
if (navigationStack.contains(screenIndex)) {
// Move it to the end to show it's the most recent
navigationStack.remove(screenIndex);
}
navigationStack.add(screenIndex);
});
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false, // Prevents immediate system pop when false
onPopInvokedWithResult: (bool didPop, Object? result) async {
// If the system already handled the pop, do nothing
if (didPop) return;
// Run your custom logic (e.g., show a dialog)
final bool shouldPop = await onWillPop();
// Manually trigger pop if user confirms
if (shouldPop && context.mounted) {
Navigator.of(context).pop(result);
}
},
child: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home),label: "Home"),
BottomNavigationBarItem(icon: Icon(Icons.add_shopping_cart),label: "Cart"),
BottomNavigationBarItem(icon: Icon(Icons.person),label: "Profile"),
],
currentIndex: selectedScreenIndex,
onTap: (index){
navigateToScreen(index);
},
),
body: Stack(
children: [
Positioned.fill(
bottom: 10,
child:IndexedStack(
index: selectedScreenIndex,
children: [
Navigator(
key: homeNavigatorKey,
onGenerateRoute: (_) => MaterialPageRoute(
builder: (_) => HomeScreen(),
),
),
Navigator(
key: productNavigatorKey,
onGenerateRoute: (_) => MaterialPageRoute(
builder: (_) => ProductScreen(),
),
),
Navigator(
key: productNavigatorKey,
onGenerateRoute: (_) => MaterialPageRoute(
builder: (_) => ProfileScreen(),
),
),
],
),
),
],
),
),
);
}
}