skip to Main Content

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


  1. 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:

    Future<bool> onWillPop() async {
      var currentTime = DateTime.now();
      DateTime? lastPressedTime;
    
      // Check if the current screen is the home screen
      if (_controller.index == 0) {
        // If the navigation stack is not empty, pop the current screen
        if (Navigator.of(context).canPop()) {
          Navigator.of(context).pop();
          return false; // Prevent the default system pop behavior
        } else {
          // If the navigation stack is empty, handle exit behavior
          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 false; // Prevent the default system pop behavior
          } else {
            SystemNavigator.pop();
            exit(0);
          }
        }
      } else {
        // If the current screen is not the home screen, allow navigation back
        return true;
      }
    }
    
    Login or Signup to reply.
  2. 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:

    Future<bool> onWillPop() async {
      var currentTime = DateTime.now();
      DateTime? lastPressedTime;
      
      // Check if the current screen index is the home screen
      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 {
        // If not on the home screen, simply navigate back
        // Returning true allows the back navigation to proceed
        if (_controller.index > 0) {
          // Decrement the index to go back
          _controller.index--;
        }
        return Future.value(false); // Prevent the default back behavior
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search