Flutter navigation with Side Menu using the Drawer widget

Flutter Jun 7, 2023

Navigation menus are essential components in mobile app development, as they provide users with easy access to different sections of the application. In this post, we will learn how to create a navigation menu with a side menu in Flutter, using the Navigator class for route management.

1.  Creating our routing setup

We will start by setting up the basic structure of our Flutter app and defining the main entry point. We will do this in our main.dart file. In here we create a MaterialApp where we will set our routes, see the code snippet below:

import 'package:flutter/material.dart';
import 'package:flutter_navigation_with_the_side_menu/home_page.dart';
import 'package:flutter_navigation_with_the_side_menu/profile_page.dart';
import 'package:flutter_navigation_with_the_side_menu/settings_page.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Navigation Menu',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => HomePage(),
        '/profile': (context) => const ProfilePage(),
        '/settings': (context) => const SettingsPage(),
      },
    );
  }
}

In the routes property, we define named routes for each page of our navigation menu. The key represents the route name, and the value is the corresponding widget that should be displayed when the route is navigated to. As you can see we have three pages HomePage, ProfilePage, and the SettingsPage.

The initialRoute property of our MaterialApp is set to '/', indicating that the app should start with the HomePage widget as the initial page.

By defining named routes, we can easily navigate between pages using Navigator.pushNamed() without the need to manually instantiate and manage the pages.

With the basic structure and configuration in place, we are now ready to proceed with implementing the navigation menu with a side menu. As mentioned before we will have three pages. I prefer to have every page in a separate file so let us create the following files: home_page.dart, profile_page.dart, and settings_page.dart.

2. Creating the Side Menu using the Drawer Widget

Because the HomePage is our initial page, we want to have our side menu available on that page. In Flutter you can easily create a side menu using the Drawer widget, see the code snippet of home_page.dart below:

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Navigation Menu'),
      ),
      body: const Center(
        child: Text('Home Page'),
      ),
      drawer: Drawer(
        child: ListView(
          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: () {
                Navigator.pushNamed(context, '/');
              },
            ),
            ListTile(
              leading: const Icon(Icons.person),
              title: const Text('Profile'),
              onTap: () {
                Navigator.pushNamed(context, '/profile');
              },
            ),
            ListTile(
              leading: const Icon(Icons.settings),
              title: const Text('Settings'),
              onTap: () {
                Navigator.pushNamed(context, '/settings');
              },
            ),
          ],
        ),
      ),
    );
  }
}

In the MyHomePage class, we create a Scaffold widget that represents the main layout. It consists of an AppBar for the title, a Center widget for the body displaying the "Home Page" text, and a Drawer widget for the side menu. Inside our Drawer, we have a ListView widget to make sure that we can display multiple widgets.

Each ListTile in the side menu has an Icon a Text for the title and an onTap function that uses Navigator.pushNamed() to navigate to the desired route. These are the same routes we defined in the routes property of our MaterialApp. The menu will look like the screenshot below:

flutter_side_menu_showing_3_navigation_items

3. Creating the remaining pages

Our Navigation is ready, however we still need to create two more pages. Let us start with the ProfilePage widget inside the profile_page.dart file:

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Profile'),
      ),
      body: const Center(
        child: Text('Profile Page'),
      ),
    );
  }
}

In the above code we created our ProfilePage widget. The ProfilePage widget displays a Scaffold with the title property to show the user the page that they are on. Furthermore, we show a Text widget like we do on our home page as well. Now that we have our second page, let us create the third and final page. Here is the code for the ProfilePage widget that should be placed in the profile_page.dart:

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Settings'),
      ),
      body: const Center(
        child: Text('Settings Page'),
      ),
    );
  }
}

For the SettingsPage we did the exact same thing as for the ProfilePage. Now that we have all our pages we can try out the navigation:

flutter_navigating_between_screens_using_the_drawer_widget

As you can see we have our side menu in place and we can easily navigation between our pages. However, there is one thing I would like to address.

4. Change the Height of our DrawerHeader

Right now our DrawerHeader takes up a lot of space in our menu and we can change this by using the SizedBox widget to reduce its height:

const SizedBox(
  height: 64,
  child: DrawerHeader(
    decoration: BoxDecoration(
      color: Colors.blue,
    ),
    child: Text(
      'Menu',
      style: TextStyle(
        color: Colors.white,
        fontSize: 24,
      ),
    ),
  ),
),

In the above code snippet our DrawerHeader is wrapped by the SizedBox widget. The SizedBox widget is used to specify a fixed height of 64 for the DrawerHeader. It ensures that the header has a consistent height within the drawer.

In the screenshot below you can see that our header now matches with the AppBar of our pages:

flutter_side_menu_with_smaller_drawer_header

This looks much better in my opinion! Of course you are free to change it to whatever you like.

That is it! With this implementation, you can create a navigation menu with a side menu in your Flutter app using the Navigator class for navigation between our defined routes.

5. Summary

In this implementation:

  • We defined named routes in the routes property of the MaterialApp. Each route is associated with a corresponding page/widget.
  • The initial route is set to '/', which corresponds to the HomePage widget.
  • In the ListView of the Drawer, we used the onTap methods of each ListTile to use Navigator.pushNamed() and pass the desired route name as the second parameter.
  • When a menu item is tapped, Navigator.pushNamed() is called, which pushes the corresponding route onto the navigation stack, resulting in the desired page being displayed.
  • Each page is represented by a separate StatelessWidget class (HomePage, ProfilePage, SettingsPage). The AppBar is added to each page to display a title.

6. Conclusion

Implementing a navigation menu in Flutter using the Drawer widget is a quick way to add a side menu to your application. By using the Navigation class you can easily navigate between routes.

Tags