Bird
Raised Fist0
Fluttermobile~20 mins

Drawer navigation in Flutter - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Home Screen with Drawer
A simple app screen with a navigation drawer that slides from the left. The drawer contains three menu items: Home, Profile, and Settings. Tapping each item closes the drawer and shows a message on the main screen.
Target UI
┌─────────────────────────────┐
│☰ Home Screen               │
│                             │
│  Welcome to the Home Screen │
│                             │
│                             │
│                             │
│                             │
│                             │
└─────────────────────────────┘

Drawer (hidden by default):
┌───────────────┐
│ Home          │
│ Profile       │
│ Settings      │
└───────────────┘
Add an AppBar with a menu icon to open the drawer
Implement a Drawer with three ListTile items: Home, Profile, Settings
When a drawer item is tapped, close the drawer and update the main screen text to show which item was selected
Use Scaffold and Drawer widgets properly
Starter Code
Flutter
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  String _selectedItem = 'Home Screen';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home Screen'),
        // TODO: Add menu icon to open drawer
      ),
      drawer: Drawer(
        // TODO: Add drawer items here
      ),
      body: Center(
        child: Text(_selectedItem, style: const TextStyle(fontSize: 24)),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Solution
Flutter
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  String _selectedItem = 'Home Screen';

  void _selectItem(String item) {
    setState(() {
      _selectedItem = item;
    });
    Navigator.of(context).pop(); // Close the drawer
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home Screen'),
        leading: IconButton(
          icon: const Icon(Icons.menu),
          onPressed: () {
            Scaffold.of(context).openDrawer();
          },
          tooltip: 'Open navigation menu',
        ),
      ),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: [
            const DrawerHeader(
              decoration: BoxDecoration(color: Colors.blue),
              child: Text('Menu', style: TextStyle(color: Colors.white, fontSize: 24)),
            ),
            ListTile(
              leading: const Icon(Icons.home),
              title: const Text('Home'),
              onTap: () => _selectItem('Home Screen'),
            ),
            ListTile(
              leading: const Icon(Icons.person),
              title: const Text('Profile'),
              onTap: () => _selectItem('Profile Screen'),
            ),
            ListTile(
              leading: const Icon(Icons.settings),
              title: const Text('Settings'),
              onTap: () => _selectItem('Settings Screen'),
            ),
          ],
        ),
      ),
      body: Center(
        child: Text(_selectedItem, style: const TextStyle(fontSize: 24)),
      ),
    );
  }
}

We added a leading menu icon button in the AppBar that opens the drawer when tapped. The drawer contains a header and three ListTile items: Home, Profile, and Settings. Each ListTile has an icon and label. When tapped, the drawer closes and the main screen text updates to show which menu item was selected. We used Navigator.of(context).pop() to close the drawer. This creates a simple and clear drawer navigation experience.

Final Result
Completed Screen
┌─────────────────────────────┐
│☰ Home Screen               │
│                             │
│  Home Screen                │
│                             │
│                             │
│                             │
│                             │
│                             │
└─────────────────────────────┘

Drawer (when opened):
┌───────────────┐
│ Menu          │
│───────────────│
│ 🏠 Home       │
│ 👤 Profile    │
│ ⚙️ Settings   │
└───────────────┘
Tap the menu icon to open the drawer from the left
Tap 'Home', 'Profile', or 'Settings' to close the drawer and update the main text
The main screen text changes to 'Home Screen', 'Profile Screen', or 'Settings Screen' accordingly
Stretch Goal
Add a dark mode toggle switch inside the drawer that changes the app theme between light and dark.
💡 Hint
Use a StatefulWidget to hold the theme mode state and wrap MaterialApp with a ThemeMode property. Add a SwitchListTile in the drawer to toggle the mode.

Practice

(1/5)
1. What is the main purpose of using a Drawer in a Flutter app?
easy
A. To create a floating action button
B. To display a bottom navigation bar
C. To show a popup dialog
D. To provide a hidden side menu accessible by swipe or icon tap

Solution

  1. Step 1: Understand Drawer usage

    A Drawer is a panel that slides from the side to show navigation options.
  2. Step 2: Compare with other UI elements

    Bottom bars, dialogs, and buttons serve different purposes than a Drawer.
  3. Final Answer:

    To provide a hidden side menu accessible by swipe or icon tap -> Option D
  4. Quick Check:

    Drawer = hidden side menu [OK]
Hint: Drawer means side menu, not bottom or popup [OK]
Common Mistakes:
  • Confusing Drawer with bottom navigation
  • Thinking Drawer is a popup dialog
  • Mixing Drawer with floating buttons
2. Which Flutter widget property is used to add a drawer to a screen?
easy
A. navigationDrawer
B. sideMenu
C. drawer
D. menuPanel

Solution

  1. Step 1: Identify Scaffold properties

    The Scaffold widget has a property named drawer to add a side drawer.
  2. Step 2: Check other options

    Properties like sideMenu, navigationDrawer, or menuPanel do not exist in Scaffold.
  3. Final Answer:

    drawer -> Option C
  4. Quick Check:

    Scaffold.drawer adds the drawer [OK]
Hint: Use Scaffold.drawer to add a drawer [OK]
Common Mistakes:
  • Using non-existent properties like sideMenu
  • Trying to add drawer outside Scaffold
  • Confusing drawer with appBar property
3. What will happen if you run this Flutter code snippet?
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')),
)
medium
A. App shows a screen with an app bar, a drawer accessible by swipe or icon, and a centered welcome text
B. App crashes because DrawerHeader cannot be inside ListView
C. App shows only the drawer without the app bar or body
D. App shows an error because ListTile requires onTap callback

Solution

  1. Step 1: Analyze Scaffold structure

    The Scaffold has an appBar, a drawer with a header and list items, and a body with centered text.
  2. Step 2: Check widget usage

    DrawerHeader inside ListView is valid. ListTile without onTap is allowed but not interactive.
  3. Final Answer:

    App shows a screen with an app bar, a drawer accessible by swipe or icon, and a centered welcome text -> Option A
  4. Quick Check:

    Drawer with header and items works as expected [OK]
Hint: DrawerHeader inside ListView is valid; ListTile onTap optional [OK]
Common Mistakes:
  • Thinking DrawerHeader cannot be inside ListView
  • Assuming ListTile must have onTap
  • Expecting drawer to show automatically without user action
4. Identify the error in this Flutter code that prevents the drawer from opening:
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')),
)
medium
A. Drawer widget is missing a ListView
B. Using Scaffold.of(context) inside appBar's leading causes context error
C. IconButton icon is incorrect for drawer
D. Body widget should be a ListView for drawer to work

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    Using Scaffold.of(context) inside appBar's leading causes context error -> Option B
  4. Quick Check:

    Context must be below Scaffold to open drawer [OK]
Hint: Scaffold.of(context) needs context inside Scaffold, not appBar [OK]
Common Mistakes:
  • Assuming drawer needs ListView to open
  • Thinking icon choice affects drawer opening
  • Believing body widget type affects drawer
5. You want to create a drawer with a header and three clickable items that navigate to different screens. Which code snippet correctly implements this behavior? A)
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'); }),
    ],
  ),
)
hard
A. Uses Column with onTap that closes drawer and navigates correctly
B. Uses ListView but ListTiles have no onTap, so no navigation
C. Uses ListView with onTap only closing drawer, no navigation
D. Uses Column with onTap navigating to screens but does not close drawer

Solution

  1. Step 1: Check navigation and drawer closing

    To navigate and close drawer, use Navigator.popAndPushNamed inside onTap.
  2. Step 2: Compare layout widgets

    Column works but may cause overflow; ListView is better for scrolling but not required here.
  3. 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.
  4. Final Answer:

    Uses Column with onTap that closes drawer and navigates correctly -> Option A
  5. Quick Check:

    popAndPushNamed closes drawer and navigates [OK]
Hint: Use popAndPushNamed to close drawer and navigate [OK]
Common Mistakes:
  • Not closing drawer before navigation
  • Missing onTap handlers on ListTile
  • Using Navigator.pop only closes drawer without navigation
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard