The slide-in side menu — tap the hamburger, navigate, sign out — is a staple of apps with more destinations than a bottom bar can hold. Flutter makes it almost free: hand a Drawer to the Scaffold and it wires up the hamburger icon, the edge swipe, and the open/close animation for you. This guide covers adding the drawer, building a proper header, the menu items, closing the drawer on tap, the right-hand endDrawer, and opening it from a custom button, with paste-ready code.

The Complete Flutter Guide: Build Android, iOS and Web apps
Go from scratch to building industry-standard apps with Riverpod, Firebase, animations, REST APIs, and more.
Enrol nowEvery snippet below is paste-ready against current stable Flutter. The drawer is the third navigation pattern, alongside bottom navigation and tabs — reach for it when you have more destinations than fit comfortably elsewhere.
We'll add a drawer, build the header, list the menu items, close the drawer on tap, and cover endDrawer and opening from code.
If you'd rather watch a full app shell with a drawer built and themed, the channel covers these navigation structures end to end.
Add a drawer
Pass a Drawer to the Scaffold's drawer property and Flutter adds the hamburger icon and the edge swipe for free. Fill it with a ListView so it scrolls if the menu is long.
Scaffold(
appBar: AppBar(title: const Text('Coding Liquids')),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const [
DrawerHeader(child: Text('Menu')),
ListTile(leading: Icon(Icons.home), title: Text('Home')),
ListTile(leading: Icon(Icons.settings), title: Text('Settings')),
],
),
),
body: const HomeBody(),
)
Note padding: EdgeInsets.zero on the ListView — without it the header sits below an unwanted top gap, because ListView adds default padding inside the drawer.
A proper header
DrawerHeader gives you a styled top block, but for an account menu, UserAccountsDrawerHeader is purpose-built — it lays out an avatar, a name, and an email in the standard Material arrangement.
UserAccountsDrawerHeader(
accountName: const Text('Sagnik Bhattacharya'),
accountEmail: const Text('hello@codingliquids.com'),
currentAccountPicture: const CircleAvatar(
child: Text('S'),
),
)
This is the quickest way to a polished header. Use plain DrawerHeader with a gradient or logo when the menu isn't account-centric, and UserAccountsDrawerHeader when it is.

Build a full app navigation shell
The Complete Flutter Guide wires drawers, tabs, and bottom bars into real, shipped apps.
Enrol nowClose the drawer on tap
The open drawer is a route on the navigation stack, so a menu item must close it before — or as part of — navigating. Pop the drawer first inside the ListTile's onTap, then push the destination.
ListTile(
leading: const Icon(Icons.settings),
title: const Text('Settings'),
onTap: () {
Navigator.pop(context); // close the drawer
Navigator.pushNamed(context, '/settings');
},
)
Skip the pop and the drawer stays open over the new screen — a classic first-app bug. The pattern is always: close the drawer, then navigate, as covered in the navigation basics.
endDrawer and opening from code
The endDrawer property gives you a second drawer that opens from the right edge — handy for filters or a secondary panel. To open either drawer from your own button, call Scaffold.of(context).openDrawer() (or openEndDrawer()), making sure the context sits below the Scaffold.
Builder(
builder: (context) => IconButton(
icon: const Icon(Icons.menu),
onPressed: () => Scaffold.of(context).openDrawer(),
),
)
The Builder matters: a context taken directly in the Scaffold's own build method is above the Scaffold, so Scaffold.of can't find it. Wrapping the button in a Builder — or using a GlobalKey<ScaffoldState> — gives you a context below it.
Common mistakes
- Forgetting padding: EdgeInsets.zero. The ListView's default padding pushes the header down.
- Not popping the drawer on tap. It stays open over the destination screen.
- Scaffold.of with the wrong context. Use a
Builderor a GlobalKey so the context is below the Scaffold. - A non-scrolling Column for many items. Use a
ListViewso long menus scroll. - Overloading the drawer. For three to five primary destinations, a bottom bar is usually clearer.
Frequently asked questions
How do I add a navigation drawer in Flutter?
Pass a Drawer to the Scaffold's drawer property; Flutter adds the hamburger icon and edge swipe automatically.
How do I close the drawer when a menu item is tapped in Flutter?
Call Navigator.pop(context) in the ListTile's onTap before navigating, since the open drawer is a route on the stack.
What is the difference between drawer and endDrawer in Flutter?
drawer opens from the left as the main menu; endDrawer opens from the right for secondary panels. A Scaffold can have both.
How do I open a Flutter drawer with a custom button?
Call Scaffold.of(context).openDrawer() from a context below the Scaffold — wrap the button in a Builder or use a GlobalKey<ScaffoldState>.
Further reads
Keep going with the tutorials that pair with this guide:
- Flutter Development Guide 2026 — the full Flutter hub.
- Flutter Scaffold Explained — the drawer, body, and AppBar slots.
- Flutter BottomNavigationBar — the bottom-bar alternative for primary destinations.
- Flutter Navigation Basics — push, pop, and named routes.
- Flutter Card and ListTile — the items that fill the drawer menu.
Sources: Flutter documentation — Drawer, DrawerHeader, UserAccountsDrawerHeader, Scaffold.drawer and endDrawer, and the "Add a drawer to a screen" cookbook recipe (docs.flutter.dev). Verified against current stable Flutter.