Android back button not working with navigators inside tabs on Flutter

221

First you should create a key for your navigator

final GlobalKey<NavigatorState> homeNavigatorKey = GlobalKey();

then add this key to your navigator

Navigator(
      key: homeNavigatorKey,

then wrap your Navigator in a WillPopScope widget and add the onWillPop as follows

child: WillPopScope(
    onWillPop: () async {
      return !(await homeNavigatorKey.currentState!.maybePop());
    },
    child: Navigator(
      key: homeNavigatorKey,

this will check if the navigatorKey can pop a route or not, if yes it will pop this route only if no it will pop itself thus closing the app

Share:
221
Vitor Estevam
Author by

Vitor Estevam

Updated on December 30, 2022

Comments

  • Vitor Estevam
    Vitor Estevam over 1 year

    I need a navigator inside each tab, so when I push a new Widget, the tab bar keeps on screen. The Code is working very well, but the android back button is closing the app instead of running Navigator.pop()

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const TabBarDemo());
    }
    
    class TabBarDemo extends StatelessWidget {
      const TabBarDemo({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: DefaultTabController(
            length: 1,
            child: Scaffold(
              bottomNavigationBar: const BottomAppBar(
                color: Colors.black,
                child: TabBar(
                  tabs: [
                    Tab(icon: Icon(Icons.directions_car)),
                  ],
                ),
              ),
              body: TabBarView(
                children: [
                  Navigator(
                    onGenerateRoute: (settings) {
                      return MaterialPageRoute(
                        builder: (context) => IconButton(
                            icon: Icon(Icons.directions_car),
                            onPressed: () => Navigator.of(context).push(
                                MaterialPageRoute(
                                    builder: (context) => newPage()))),
                      );
                    },
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    class newPage extends StatelessWidget {
      const newPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("new page"),
          ),
          body: Center(child: Icon(Icons.add)),
        );
      }
    }
    

    the code is also available here but on dartpad you cannot test the android back button.

    • Vitor Estevam
      Vitor Estevam over 2 years
      in my tests it's as if the new navigator, inside the tab, wasn't "overlapping" the root navigator from MaterialApp