Close Navigation Drawer on Back Button Pressed in Flutter
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
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);
}
}
Md. Asaduzzaman
I am an enthusiastic mobile application developer both in Android and iOS
Updated on December 18, 2022Comments
-
Md. Asaduzzaman over 1 year
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 showAlertDialog
. The application just showAlertDialog
instead of close the Drawer when back press. I want Drawer should close if already open and showAlertDialog
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?