A drawer navigation lets users open a hidden menu from the side of the screen. It helps keep the app clean and easy to use by hiding extra options until needed.
Drawer navigation in Flutter
Scaffold(
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(child: Text('Header')),
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
],
),
),
appBar: AppBar(title: Text('Title')),
body: Center(child: Text('Main content')),
)The drawer property of Scaffold adds the side menu.
Use DrawerHeader for a top section inside the drawer.
Scaffold(
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(child: Text('Menu')),
ListTile(title: Text('Home')),
ListTile(title: Text('Settings')),
],
),
),
appBar: AppBar(title: Text('App')),
body: Center(child: Text('Welcome')),
)Column instead of ListView inside the drawer.Scaffold(
drawer: Drawer(
child: Column(
children: [
DrawerHeader(child: Text('User Info')),
ListTile(title: Text('Profile')),
ListTile(title: Text('Logout')),
],
),
),
appBar: AppBar(title: Text('Profile Page')),
body: Center(child: Text('User details here')),
)This app shows a drawer menu with a header and two items. The drawer opens when you swipe from the left or tap the menu icon in the app bar.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Drawer Navigation Example')), drawer: Drawer( child: ListView( padding: EdgeInsets.zero, children: [ DrawerHeader( decoration: BoxDecoration(color: Colors.blue), child: Text('Menu', style: TextStyle(color: Colors.white, fontSize: 24)), ), ListTile( leading: Icon(Icons.home), title: Text('Home'), onTap: () { Navigator.pop(context); }, ), ListTile( leading: Icon(Icons.settings), title: Text('Settings'), onTap: () { Navigator.pop(context); }, ), ], ), ), body: Center(child: Text('Swipe from left or tap top-left icon to open drawer')), ), ); } }
Always include Navigator.pop(context) in onTap to close the drawer after selection.
Drawer works best with Scaffold as its parent widget.
Use EdgeInsets.zero padding in ListView to avoid unwanted space at top.
Drawer navigation hides menu options in a side panel accessible by swipe or icon tap.
Use Scaffold with the drawer property to add a drawer.
Include a header and list items inside the drawer for a clear menu.
Practice
Drawer in a Flutter app?Solution
Step 1: Understand Drawer usage
A Drawer is a panel that slides from the side to show navigation options.Step 2: Compare with other UI elements
Bottom bars, dialogs, and buttons serve different purposes than a Drawer.Final Answer:
To provide a hidden side menu accessible by swipe or icon tap -> Option DQuick Check:
Drawer = hidden side menu [OK]
- Confusing Drawer with bottom navigation
- Thinking Drawer is a popup dialog
- Mixing Drawer with floating buttons
Solution
Step 1: Identify Scaffold properties
The Scaffold widget has a property nameddrawerto add a side drawer.Step 2: Check other options
Properties likesideMenu,navigationDrawer, ormenuPaneldo not exist in Scaffold.Final Answer:
drawer -> Option CQuick Check:
Scaffold.drawer adds the drawer [OK]
- Using non-existent properties like sideMenu
- Trying to add drawer outside Scaffold
- Confusing drawer with appBar property
Scaffold(
appBar: AppBar(title: Text('Home')),
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(child: Text('Menu')),
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
],
),
),
body: Center(child: Text('Welcome')),
)Solution
Step 1: Analyze Scaffold structure
The Scaffold has an appBar, a drawer with a header and list items, and a body with centered text.Step 2: Check widget usage
DrawerHeader inside ListView is valid. ListTile without onTap is allowed but not interactive.Final Answer:
App shows a screen with an app bar, a drawer accessible by swipe or icon, and a centered welcome text -> Option AQuick Check:
Drawer with header and items works as expected [OK]
- Thinking DrawerHeader cannot be inside ListView
- Assuming ListTile must have onTap
- Expecting drawer to show automatically without user action
Scaffold(
appBar: AppBar(
title: Text('App'),
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () {
Scaffold.of(context).openDrawer();
},
),
),
drawer: Drawer(child: Text('Menu')),
body: Center(child: Text('Content')),
)Solution
Step 1: Understand context usage in Scaffold
Calling Scaffold.of(context) inside appBar's leading uses a context that is above Scaffold, causing an error.Step 2: Identify correct way to open drawer
Use a Builder widget or a GlobalKey to get a context below Scaffold to open drawer properly.Final Answer:
Using Scaffold.of(context) inside appBar's leading causes context error -> Option BQuick Check:
Context must be below Scaffold to open drawer [OK]
- Assuming drawer needs ListView to open
- Thinking icon choice affects drawer opening
- Believing body widget type affects drawer
Drawer(
child: Column(
children: [
DrawerHeader(child: Text('Header')),
ListTile(title: Text('Screen 1'), onTap: () { Navigator.popAndPushNamed(context, '/screen1'); }),
ListTile(title: Text('Screen 2'), onTap: () { Navigator.popAndPushNamed(context, '/screen2'); }),
ListTile(title: Text('Screen 3'), onTap: () { Navigator.popAndPushNamed(context, '/screen3'); }),
],
),
)
B) Drawer(
child: ListView(
children: [
DrawerHeader(child: Text('Header')),
ListTile(title: Text('Screen 1')),
ListTile(title: Text('Screen 2')),
ListTile(title: Text('Screen 3')),
],
),
)
C) Drawer(
child: ListView(
children: [
DrawerHeader(child: Text('Header')),
ListTile(title: Text('Screen 1'), onTap: () { Navigator.pop(context); }),
ListTile(title: Text('Screen 2'), onTap: () { Navigator.pop(context); }),
ListTile(title: Text('Screen 3'), onTap: () { Navigator.pop(context); }),
],
),
)
D) Drawer(
child: Column(
children: [
DrawerHeader(child: Text('Header')),
ListTile(title: Text('Screen 1'), onTap: () { Navigator.pushNamed(context, '/screen1'); }),
ListTile(title: Text('Screen 2'), onTap: () { Navigator.pushNamed(context, '/screen2'); }),
ListTile(title: Text('Screen 3'), onTap: () { Navigator.pushNamed(context, '/screen3'); }),
],
),
)Solution
Step 1: Check navigation and drawer closing
To navigate and close drawer, use Navigator.popAndPushNamed inside onTap.Step 2: Compare layout widgets
Column works but may cause overflow; ListView is better for scrolling but not required here.Step 3: Evaluate options
Column with pushNamed navigates but drawer stays open; ListView without onTap has no navigation; ListView with pop only closes drawer; Column with popAndPushNamed closes drawer and navigates properly.Final Answer:
Uses Column with onTap that closes drawer and navigates correctly -> Option AQuick Check:
popAndPushNamed closes drawer and navigates [OK]
- Not closing drawer before navigation
- Missing onTap handlers on ListTile
- Using Navigator.pop only closes drawer without navigation
Ready to prove it?
Pass the test and this pattern moves unknown
