Add a drawer to a screen
In apps that use Material Design, there are two primary options for navigation: tabs and drawers. When there is insufficient space to support tabs, drawers provide a handy alternative.
                  In Flutter, use the Drawer
                   widget in combination with a
                  Scaffold
                   to create a layout with a Material Design drawer.
                  This recipe uses the following steps:
                
- Create a Scaffold.
- Add a drawer.
- Populate the drawer with items.
- Close the drawer programmatically.
1. Create a Scaffold
                  #
                
                  To add a drawer to the app, wrap it in a Scaffold
                   widget.
                  The Scaffold widget provides a consistent visual structure to apps that
                  follow the Material Design Guidelines.
                  It also supports special Material Design
                  components, such as Drawers, AppBars, and SnackBars.
                
In this example, create a Scaffold with a drawer:
Scaffold(
  appBar: AppBar(title: const Text('AppBar without hamburger button')),
  drawer: // Add a Drawer here in the next step.
);
2. Add a drawer
#
                  Now add a drawer to the Scaffold. A drawer can be any widget,
                  but it's often best to use the Drawer widget from the
                  material library,
                  which adheres to the Material Design spec.
                
Scaffold(
  appBar: AppBar(title: const Text('AppBar with hamburger button')),
  drawer: Drawer(
    child: // Populate the Drawer in the next step.
  ),
);
3. Populate the drawer with items
#
                  Now that you have a Drawer in place, add content to it.
                  For this example, use a ListView.
                  While you could use a Column widget,
                  ListView is handy because it allows users to scroll
                  through the drawer if the
                  content takes more space than the screen supports.
                
                  Populate the ListView with a DrawerHeader
                  
                  and two ListTile
                   widgets.
                  For more information on working with Lists,
                  see the list recipes.
                
Drawer(
  // Add a ListView to the drawer. This ensures the user can scroll
  // through the options in the drawer if there isn't enough vertical
  // space to fit everything.
  child: ListView(
    // Important: Remove any padding from the ListView.
    padding: EdgeInsets.zero,
    children: [
      const DrawerHeader(
        decoration: BoxDecoration(color: Colors.blue),
        child: Text('Drawer Header'),
      ),
      ListTile(
        title: const Text('Item 1'),
        onTap: () {
          // Update the state of the app.
          // ...
        },
      ),
      ListTile(
        title: const Text('Item 2'),
        onTap: () {
          // Update the state of the app.
          // ...
        },
      ),
    ],
  ),
);
4. Open the drawer programmatically
#
                  Typically, you don't need to write any code to open a drawer,
                  Because when the leading widget is null, the default implementation in 
                  AppBar is DrawerButton.
                
                  But if you want to have free control of the drawer.
                  You can do this by using the Builder call Scaffold.of(context).openDrawer().
                
Scaffold(
  appBar: AppBar(
    title: const Text('AppBar with hamburger button'),
    leading: Builder(
      builder: (context) {
        return IconButton(
          icon: const Icon(Icons.menu),
          onPressed: () {
            Scaffold.of(context).openDrawer();
          },
        );
      },
    ),
  ),
  drawer: Drawer(
    child: // Populate the Drawer in the last step.
  ),
);
5. Close the drawer programmatically
#
                  After a user taps an item, you might want to close the drawer.
                  You can do this by using the Navigator.
                
                  When a user opens the drawer, Flutter adds the drawer to the navigation
                  stack. Therefore, to close the drawer, call Navigator.pop(context).
                
ListTile(
  title: const Text('Item 1'),
  onTap: () {
    // Update the state of the app
    // ...
    // Then close the drawer
    Navigator.pop(context);
  },
),
Interactive example
#
                  This example shows a Drawer
                   as it is used within a Scaffold
                   widget.
                  The Drawer
                   has three ListTile
                   items.
                  The _onItemTapped function changes the selected item's index
                  and displays the corresponding text in the center of the Scaffold.
                
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  static const appTitle = 'Drawer Demo';
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  static const TextStyle optionStyle = TextStyle(
    fontSize: 30,
    fontWeight: FontWeight.bold,
  );
  static const List<Widget> _widgetOptions = <Widget>[
    Text('Index 0: Home', style: optionStyle),
    Text('Index 1: Business', style: optionStyle),
    Text('Index 2: School', style: optionStyle),
  ];
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        leading: Builder(
          builder: (context) {
            return IconButton(
              icon: const Icon(Icons.menu),
              onPressed: () {
                Scaffold.of(context).openDrawer();
              },
            );
          },
        ),
      ),
      body: Center(child: _widgetOptions[_selectedIndex]),
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough vertical
        // space to fit everything.
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: [
            const DrawerHeader(
              decoration: BoxDecoration(color: Colors.blue),
              child: Text('Drawer Header'),
            ),
            ListTile(
              title: const Text('Home'),
              selected: _selectedIndex == 0,
              onTap: () {
                // Update the state of the app
                _onItemTapped(0);
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              title: const Text('Business'),
              selected: _selectedIndex == 1,
              onTap: () {
                // Update the state of the app
                _onItemTapped(1);
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              title: const Text('School'),
              selected: _selectedIndex == 2,
              onTap: () {
                // Update the state of the app
                _onItemTapped(2);
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}Unless stated otherwise, the documentation on this site reflects Flutter 3.35.5. Page last updated on 2025-10-28. View source or report an issue.