androidflutterdartmaterial-design

Close Navigation Drawer on Back Button Pressed in Flutter


I have a material designed Navigation Drawer in my very first flutter app. This work's fine but I did't find any way to close the Navigation Drawer on Back Button Press if it's open when use WillPopScope to show AlertDialog. The application just show AlertDialog instead of close the Drawer when back press. I want Drawer should close if already open and show AlertDialog otherwise.

@override
Widget build(BuildContext context) {
  return WillPopScope(
    onWillPop: onBackPressed,
    child: Scaffold(
      appBar: AppBar(
        title: Text("Home"),
      ),
      drawer: Drawer(
      ),
      body: Center(
        child: Text("Home"),
      ),
    ),
  );
}

onBackPressed shows dialog to close the app.

Future<bool> onBackPressed() {
  return showDialog(
      barrierDismissible: false,
      context: context,
      builder: (context) => AlertDialog(
            title: Text("Do you want to exit?"),
            actions: <Widget>[
              FlatButton(
                  onPressed: () => Navigator.pop(context, false),
                  child: Text("No")),
              FlatButton(
                  onPressed: () => Navigator.pop(context, true),
                  child: Text("Yes"))
            ],
          ));
}

Can anybody guide me how can I achieve this?


Solution

  • You can copy paste run full code below
    Step 1: You need Scaffold key to controll Drawer so you need GlobalKey<ScaffoldState> _key = new GlobalKey<ScaffoldState>();
    Step 2: In onWillPop You can check isDrawerOpen and do Navigator.pop

    code snippet

     GlobalKey<ScaffoldState> _key = new GlobalKey<ScaffoldState>();
    
      MyHomePage({Key key, this.title}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            if (_key.currentState.isDrawerOpen) {
              Navigator.of(context).pop();
              return false;
            }
            return true;
          },
          child: Scaffold(
    

    working demo

    enter image description here

    full code

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            print("My App Page");
            //return false;
          },
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: MyHomePage(title: "test",),
          ),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      final String title;
      GlobalKey<ScaffoldState> _key = new GlobalKey<ScaffoldState>();
    
      MyHomePage({Key key, this.title}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            if (_key.currentState.isDrawerOpen) {
              Navigator.of(context).pop();
              return false;
            }
            return true;
          },
          child: Scaffold(
            key: _key,
            appBar: AppBar(title: Text(title)),
            body: Center(child: Text('My Page!')),
            drawer: Drawer(
              child: ListView(
                padding: EdgeInsets.zero,
                children: <Widget>[
                  DrawerHeader(
                    child: Text('Drawer Header'),
                    decoration: BoxDecoration(
                      color: Colors.blue,
                    ),
                  ),
                  ListTile(
                    title: Text('page 2'),
                    onTap: () {
                      Navigator.push(
                          context, new MaterialPageRoute(builder: (context) => Page2()));
                    },
                  ),
                  ListTile(
                    title: Text('Item 2'),
                    onTap: () {
                      // Update the state of the app
                      // ...
                      // Then close the drawer
                      Navigator.pop(context);
                    },
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    
    class Page2 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            print("Page2");
            _popNavigationWithResult(context, 'from_back');
            return false;
          },
          child: Scaffold(
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                _popNavigationWithResult(context, 'from_button');
              },
            ),
            body: Container(
              child: Center(
                child: Text('Page 2',
                    style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold)),
              ),
            ),
          ),
        );
      }
    
      void _popNavigationWithResult(BuildContext context, dynamic result) {
        Navigator.pop(context, result);
      }
    }