In my Flutter app, the flow starts with a splash screen that opens a new screen navigation menu on the homepage. However, when navigating to the product details screen from the homepage and then attempting to go back, the app’s exit prompt appears, but ideally this should not happen, as I am not on the home screen. How can I resolve this issue?"
I used a WillPopScope for exit app and this function i check a _controller.index.
how i can show the only Fluttertoast and exit when app in HomeScreen Only. when app if inside a home to other screen then don’t exit;
I used a this package https://pub.dev/packages/persistent_bottom_nav_bar
NavigationMenu.dart –
class NavigationMenuState extends State<NavigationMenu> {
bool isBottomBarVisible = true;
final PersistentTabController _controller = PersistentTabController(initialIndex: 0);
@override
void initState() {
super.initState();
loadCart();
}
void loadCart() async {
final cart = Provider.of<Cart>(context, listen: false);
await cart.loadCart();
}
Future<bool> onWillPop() async {
var currentTime = DateTime.now();
DateTime? lastPressedTime;
if (_controller.index == 0 && !Navigator.of(context).canPop()) {
if (lastPressedTime == null || currentTime.difference(lastPressedTime!) > Duration(seconds: 2)) {
lastPressedTime = currentTime;
Fluttertoast.showToast(
msg: 'Press again to exit',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 2,
textColor: Colors.white,
fontSize: 15.0,
);
return Future.value(false);
} else {
SystemNavigator.pop();
exit(0);
}
} else {
return Future.value(true);
}
}
@override
Widget build(BuildContext context) {
final cart = Provider.of<Cart>(context);
return Scaffold(
body: WillPopScope(
onWillPop: onWillPop,
child: PersistentTabView(
context,
navBarHeight: 70,
controller: _controller,
popAllScreensOnTapOfSelectedTab: true,
onItemSelected: (int index) {
setState(() {
_controller.index = index;
});
},
screens: [
_buildScreenWithPadding(const HomePage()),
_buildScreenWithPadding(Container(color: Colors.redAccent)),
_buildScreenWithPadding(const CartScreen()),
_buildScreenWithPadding(Container(color: Colors.orange)),
_buildScreenWithPadding(Container(color: Colors.amber)),
],
items: [
PersistentBottomNavBarItem(
icon: const Icon(Iconsax.home),
title: 'Home',
activeColorPrimary: Colors.redAccent,
inactiveColorPrimary: Colors.grey,
routeAndNavigatorSettings: RouteAndNavigatorSettings(
initialRoute: "/home-page",
routes: {
"/home-page": (final context) => const HomePage(),
"/service-list": (final context) => const Service_List(),
},
),
),
PersistentBottomNavBarItem(
icon: const Icon(Iconsax.user),
title: 'Account',
activeColorPrimary: Colors.redAccent,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
onPressed: (BuildContext? context) {
if(context != null) {
PersistentNavBarNavigator.pushNewScreen(
context,
screen: const CartScreen(),
withNavBar: false,
);
}
},
icon: Stack(
children: [
Padding(
padding: EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () {
if(context != null) {
PersistentNavBarNavigator.pushNewScreen(
context,
screen: const CartScreen(),
withNavBar: false,
);
}
},
child: Icon(Icons.shopping_cart, size: 45, color: Colors.white,),
),
),
Positioned(
right: 5,
top: 5,
child: Container(
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
spreadRadius: 1,
blurRadius: 3,
offset: const Offset(0, 2),
),
],
),
constraints: const BoxConstraints(
minWidth: 15,
minHeight: 15,
),
child: Text(
'${cart.itemCount}',
style: const TextStyle(
color: Colors.white,
fontSize: 14,
decoration: TextDecoration.none,
),
textAlign: TextAlign.center,
),
),
),
],
),
activeColorPrimary: Colors.redAccent,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Iconsax.message_question),
title: 'Help',
activeColorPrimary: Colors.redAccent,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Iconsax.calendar),
title: 'Booking',
activeColorPrimary: Colors.redAccent,
inactiveColorPrimary: Colors.grey,
),
],
confineInSafeArea: true,
backgroundColor: Colors.white,
resizeToAvoidBottomInset: true,
stateManagement: true,
hideNavigationBarWhenKeyboardShows: true,
decoration: NavBarDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 0.5,
blurRadius: 7,
offset: const Offset(0, 3),
),
],
borderRadius: BorderRadius.circular(10.0),
),
navBarStyle: NavBarStyle.style15,
),
),
);
}
Widget _buildScreenWithPadding(Widget screen) {
return Scaffold(
body: screen,
);
}
}
2
Answers
To achieve the desired behavior of showing the exit prompt only when the user is on the home screen and attempting to exit, you can modify the onWillPop method in your NavigationMenuState class. Currently, it checks if the current index is 0 (which corresponds to the home screen) and if the navigation stack is empty. However, this logic may not work as expected because even if you’re on other screens, the navigation stack might still be empty.
Here’s a revised version of the onWillPop method:
To prevent the app from exiting when the user is on a screen other than the home screen, you can modify your onWillPop function to conditionally handle the back navigation based on the current screen index. Here’s how you can do it: