Flutter Drawer
Create sliding navigation menus
📱 What is a Drawer?
A Drawer is a sliding panel that appears from the side of the screen, typically containing navigation links and app options. It's commonly accessed via a hamburger menu icon and provides an elegant way to organize navigation in mobile applications.
// Add drawer to Scaffold
Scaffold(
drawer: Drawer(child: ListView(...)),
)
Key Drawer Concepts
Drawer Widget
The main sliding panel container
drawer: Drawer(
child: ListView(...)
)
DrawerHeader
Header section with user info
DrawerHeader(
child: Text('Menu')
)
ListTile
Menu items with icons
ListTile(
leading: Icon(Icons.home),
title: Text('Home')
)
Navigation
Navigate on item tap
onTap: () {
Navigator.pop(context);
}
🔹 Basic Drawer
Create a simple drawer with menu items:
import 'package:flutter/material.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Drawer 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); // Close drawer
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
body: Center(
child: Text('Swipe from left or tap menu icon'),
),
);
}
}
Result:
✅ Hamburger menu icon appears in AppBar
✅ Drawer slides in from left when tapped
✅ Menu items are clickable
🔹 Drawer with UserAccountsDrawerHeader
Add user profile information to the drawer header:
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
UserAccountsDrawerHeader(
accountName: Text('John Doe'),
accountEmail: Text('[email protected]'),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,
child: Text(
'JD',
style: TextStyle(fontSize: 40.0),
),
),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.person),
title: Text('Profile'),
onTap: () {
Navigator.pop(context);
},
),
Divider(), // Add a divider line
ListTile(
leading: Icon(Icons.logout),
title: Text('Logout'),
onTap: () {
Navigator.pop(context);
},
),
],
),
)
Features:
✅ User name and email displayed
✅ Profile picture with initials
✅ Divider separates menu sections
🔹 Drawer with Navigation
Navigate to different screens from drawer items:
class MyDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Text(
'Navigation Menu',
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.pop(context); // Close drawer
Navigator.pushNamed(context, '/'); // Navigate to home
},
),
ListTile(
leading: Icon(Icons.shopping_cart),
title: Text('Products'),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, '/products');
},
),
ListTile(
leading: Icon(Icons.favorite),
title: Text('Favorites'),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, '/favorites');
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, '/settings');
},
),
],
),
);
}
}
Important:
-
Always call
Navigator.pop(context)first to close the drawer - Then navigate to the desired screen
- This prevents the drawer from staying open
🔹 End Drawer (Right Side)
Add a drawer that opens from the right side:
Scaffold(
appBar: AppBar(
title: Text('End Drawer Example'),
),
// Regular drawer on left
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(child: Text('Left Menu')),
ListTile(title: Text('Item 1')),
],
),
),
// End drawer on right
endDrawer: Drawer(
child: ListView(
children: [
DrawerHeader(child: Text('Right Menu')),
ListTile(title: Text('Filter Options')),
ListTile(title: Text('Sort By')),
],
),
),
body: Center(child: Text('App Content')),
)
Result:
✅ Left drawer opens from left side (hamburger icon)
✅ Right drawer opens from right side (menu icon on right)
🔹 Custom Styled Drawer
Create a beautifully styled drawer:
drawer: Drawer(
child: Container(
color: Colors.grey[100],
child: ListView(
padding: EdgeInsets.zero,
children: [
Container(
height: 200,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 50,
backgroundColor: Colors.white,
child: Icon(Icons.person, size: 50, color: Colors.blue),
),
SizedBox(height: 10),
Text(
'Welcome User',
style: TextStyle(color: Colors.white, fontSize: 20),
),
],
),
),
SizedBox(height: 10),
_buildDrawerItem(Icons.home, 'Home', () {}),
_buildDrawerItem(Icons.notifications, 'Notifications', () {}),
_buildDrawerItem(Icons.message, 'Messages', () {}),
Divider(),
_buildDrawerItem(Icons.settings, 'Settings', () {}),
_buildDrawerItem(Icons.help, 'Help', () {}),
],
),
),
)
Widget _buildDrawerItem(IconData icon, String title, VoidCallback onTap) {
return ListTile(
leading: Icon(icon, color: Colors.blue),
title: Text(title, style: TextStyle(fontSize: 16)),
onTap: onTap,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
);
}
🔹 Complete Example
A full working drawer implementation:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Drawer Demo',
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
backgroundColor: Colors.blue,
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
UserAccountsDrawerHeader(
accountName: Text('Flutter Developer'),
accountEmail: Text('[email protected]'),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,
child: Text('FD', style: TextStyle(fontSize: 24)),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => Navigator.pop(context),
),
ListTile(
leading: Icon(Icons.star),
title: Text('Favorites'),
onTap: () => Navigator.pop(context),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
onTap: () => Navigator.pop(context),
),
Divider(),
ListTile(
leading: Icon(Icons.exit_to_app),
title: Text('Logout'),
onTap: () => Navigator.pop(context),
),
],
),
),
body: Center(
child: Text(
'Tap the menu icon to open drawer',
style: TextStyle(fontSize: 18),
),
),
);
}
}