Flutter - how avoid pushing same route twice?

Viewed 1328

This structure of my app navigation:

CupertinoTabScaffold ->tabBuilder:TabPage-> tabBar: CupertinoTabBar

My TabPage:

return MaterialApp(
  navigatorKey: navKey,    
  home: child,
);

I have separate navigation in each tab. by clicking on the bottom tab, I go back to the beginning. this is my code and this is working now:

 key.currentState!.pushNamedAndRemoveUntil('/', ModalRoute.withName('/'));

for each tab I have my own navigation key. I pass it to each TabPage.

but if the page is at the root I need to avoid pushing same route twice. I tried this code but it doesn't work:

  key.currentState!.pushNamedAndRemoveUntil("/",
    (route) => route.isFirst && route.settings.name == "/" ? false : true);

how avoid pushing same route twice?

3 Answers
Navigator.of(context).pushNamedAndRemoveUntil(
   "newRouteName",
   (route) => route.isCurrent && route.settings.name == "newRouteName"
  ? false
  : true);

t will pop the current route if name of the route is "newRouteName" and then push new one, else will not pop anything.

Edit: Latest flutter provides ModalRoute.of(context).settings.name to get the name of current route.

This will pop the current route if name of the route is the new Route Name and then push new one, else will not pop any route.

Navigator.of(context).pushNamedAndRemoveUntil(
  "new",
  (route) => route.isCurrent && ModalRoute.of(context).settings.name == "new"
      ? false
      : true);

If you're using a BottomNavigationBar, you can simply add a checker on onTap() to see if you're going to navigate on the same page. To track the current page, you can either use enum or a simple variables like int. CupertinoTabBar also have an onTap property available similar to BottomNavigationBar.

BottomNavigationBar(
  items: <BottomNavigationBarItem>[...],
  currentIndex: _currentPage,
  onTap: (value){
    // Only navigate if a different page was clicked
    if(value != _currentPage){
      _currentPage = value;
      setState(() {
        switch(value) {
          // Page 0
          case 0:
            key.currentState!.pushReplacementNamed(...);
            break;
          // Page 1
          case 1:
            key.currentState!.pushReplacementNamed(...);
            break;
          
          ...
        }
      });
    }
  }
)

Or if you're using a TabBar with TabBarView, the page displayed can be managed by the controller as demonstrated in this guide.

Related