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),
        ),
      ),
    );
  }
}

🧠 Test Your Knowledge

Which widget is used to create a sliding menu panel?