Android App Exits on Press on Back Button Instead of Navigating to Previous Screen - Flutter

1,267

Solution 1

This is how I make it works by referring this:

class _MyAppState extends State<MyApp> {
  final _navigatorKey = GlobalKey<NavigatorState>();//define a navigation key.

  @override
  Widget build(BuildContext context) {
     return MaterialApp(
        title: 'My APP',
        navigatorKey: _navigatorKey,//this is the navigation key
        onGenerateRoute: (_) => null,
        builder: (context, child) {
            return Navigator(
                key: _navigatorKey,//same navigation key
                pages: [
                    MaterialPage(
                      key: const ValueKey('homepage'),
                      child: HomPage(),//homepage widget
                     ....
                ],
                onPopPage: (route, result) {
                   //pop logic here. 
                }
            );
        }
     );
  }
}

The discussion here also mention using WillPopScope wrapper, maybe you can try this as well.

Solution 2

I believe this is happening because you're pushing to your own Navigator while the OS level back gesture and your _onBackPressed function are popping from MaterialApp's navigator. Since the latter hasn't had any routes pushed it, it behaves as expected and exits the app.

This Github issue covers the problem in detail with a couple different solutions. You could create a global key in main and pass it to materialApp using the navigatorKey argument and to DashboardNavigator using its key argument. This way, both MaterialApp and your DashboardNavigator will use the same navigator wherever you push or pop.

Share:
1,267
Ruban Thilak
Author by

Ruban Thilak

Updated on December 18, 2022

Comments

  • Ruban Thilak
    Ruban Thilak over 1 year

    This is main.dart

    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.portraitUp,
        ]);
    
        return MaterialApp(
            title: 'List',
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              primarySwatch: Colors.green,
            ),
            home: HomeScreen());
      }
    }
    

    This is homescreen.dart

    class HomeScreen extends StatefulWidget {
      HomeScreen({Key key}) : super(key: key);
    
      @override
      _HomeScreenState createState() => _HomeScreenState();
    }
    
    class _HomeScreenState extends State<HomeScreen> {
    
      int _currentindex = 0;
      final List<Widget> screen = [
        DashboardNavigator(),
        RegisterPage(),
      ];
    
      Future<bool> _onBackPressed() {
      return showDialog(
        context: context,
        builder: (context) => new AlertDialog(
          title: new Text('Are you sure ?'),
          content: new Text('Do you want to exit ?'),
          actionsPadding: EdgeInsets.only(right:10.0,bottom:10.0),
          actions: <Widget>[
            new GestureDetector(
              onTap: () => Navigator.of(context).pop(false),
              child: Text("No",
              style:TextStyle(
                color:Colors.red
              )),
            ),
            SizedBox(height: 16),
            new GestureDetector(
              onTap: () => Navigator.of(context).pop(true),
              child: Text("Yes",
              style:TextStyle(
                color:Colors.green
              )),
            ),
          ],
        ),
      ) ??
          false;
    }
    
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
        onWillPop:_onBackPressed,
        child:Scaffold(
              body: SafeArea(
                child: IndexedStack(
                  index:_currentindex,
                  children: screen,
                )
                ),
                bottomNavigationBar: BottomNavigationBar(
                currentIndex: _currentindex,
                onTap: (int index) {
                  this.setState(() {
                    _currentindex = index;
                    }
                  );
                },
                items:[
                  BottomNavigationBarItem(icon: Icon(Icons.home,color:Colors.green),title:Text('Home')),
                  BottomNavigationBarItem(icon: Icon(Icons.settings_ethernet,color:Colors.green),title:Text('Console')),
                ]
              )
        ));
      }
    }
    

    This is the Navigator Widget

    class DashboardNavigator extends StatefulWidget {
      DashboardNavigator({Key key}) : super(key: key);
    
      @override
      _DashboardNavigatorState createState() => _DashboardNavigatorState();
    }
    
    class _DashboardNavigatorState extends State<DashboardNavigator> {
    
      String url;
    
      @override
      Widget build(BuildContext context) {
        return Navigator(
          onGenerateRoute: (RouteSettings settings) {
            return MaterialPageRoute(
              settings: settings,
              builder: (BuildContext context) {
                switch(settings.name) {
                  case '/':
                    return DashBoard();
                  case '/listhub':
                    return ListHub();
                  case '/listhub/listfarmer':
                    return ListFarmer(url);
                }
              },
            );
          }
        );
      }
    }
    

    I used Navigator.pushNamed function to navigate between these screen

    onPressed: () => Navigator.pushNamed(context,"/listhub"),

    but when i click on the android back button it closes the app instead of navigating to the previous page ... I tried WillpopScope in each page but it doesn't work.

    Please Suggest me the correct way to navigate back to the previous screen using android back button and also appBar back button.