A navigation drawer is a panel which can be pulled to display a menu typically containing the primary navigation options for an application
The drawer is hidden by default and appears when a user touches any visible drawer icon or through a gesture like swipe
Flutter provides Drawer
component for implementing a navigation drawer
Navigation
component is used to route to a screen
A route is a string mapped to a Widget
object while a material app is initialized
Check Flutter installation to setup Flutter
Use flutter create
command to create a Flutter project (here nc_navigation_drawer):
flutter create nc_navigation_drawer
main.dart declares a material app with routes
which is a map of string to Widgets
import 'package:flutter/material.dart';
import 'package:navigation_drawer_app/account.dart';
import 'package:navigation_drawer_app/home.dart';
import 'package:navigation_drawer_app/settings.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: HomeScreen(), // route for home is '/' implicitly
routes: <String, WidgetBuilder>{
// declare routes
SettingsScreen.routeName: (BuildContext context) => SettingsScreen(),
AccountScreen.routeName: (BuildContext context) => AccountScreen(),
},
));
}
These route names can then be navigated to using Navigator.of(context).pushNamed(routeName);
In drawer_state.dart, a state NavigationDrawerState
is declared with getNavDrawer()
function of type Drawer
This state is to be inherited by states of stateful Widgets for them to be able to access the drawer
getNavDrawer()
returns the layout of Drawer, with navigation items which are routed based on their associated route name when clicked
import 'package:flutter/material.dart';
import 'package:navigation_drawer_app/account.dart';
import 'package:navigation_drawer_app/settings.dart';
class NavigationDrawerState extends State<StatefulWidget> {
Drawer getNavDrawer(BuildContext context) {
var headerChild = DrawerHeader(child: Text("Navigation Drawer Header"));
var aboutChild = AboutListTile(
child: Text("About"),
applicationName: "Navigation Drawer App",
applicationVersion: "v1.0.0",
applicationIcon: Icon(Icons.adb),
icon: Icon(Icons.info));
// ListTile denoting navigation item rendered for given icon and label
ListTile getNavItem(var icon, String label, String routeName) {
return ListTile(
leading: Icon(icon),
title: Text(label),
// clicking the tile initiates navigation to routeName
onTap: () {
setState(() {
// pop() closes the drawer
Navigator.of(context).pop();
// navigate to routeName
Navigator.of(context).pushNamed(routeName);
});
},
);
}
var navChildren = [
headerChild,
getNavItem(Icons.settings, "Settings", SettingsScreen.routeName),
getNavItem(Icons.home, "Home", "/"),
getNavItem(Icons.account_box, "Account", AccountScreen.routeName),
aboutChild
];
return Drawer(
child: ListView(children: navChildren);,
);
}
// kinda placeholder for build function, which gets overridden by a class inheriting this class
@override
Widget build(BuildContext context) {
return Scaffold();
}
}
Account screen whose state inherits from NavigationDrawerState and calls getNavDrawer()
to set drawer for Scaffold
that is rendered by it
import 'package:flutter/material.dart';
import 'package:navigation_drawer_app/drawer_state.dart';
class AccountScreen extends StatefulWidget {
static const String routeName = "/account";
@override
AccountScreenState createState() => AccountScreenState();
}
class AccountScreenState extends NavigationDrawerState {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Account"),
),
body: Container(
child: Center(
child: Text("Account Screen"),
)),
// Set the nav drawer
drawer: getNavDrawer(context),
);
}
}
Home screen, similar to account screen
import 'package:flutter/material.dart';
import 'package:navigation_drawer_app/drawer_state.dart';
class HomeScreen extends StatefulWidget {
@override
HomeScreenState createState() => HomeScreenState();
}
class HomeScreenState extends NavigationDrawerState {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Navigation Drawer Example"),
),
body: Container(
child: Center(
child: Text("Home Screen"),
)),
// Set the nav drawer
drawer: getNavDrawer(context),
);
}
}
Settings screen declared as a StatelessWidget, and thus cannot access drawer but gets a Back button to go to previous screen
import 'package:flutter/material.dart';
class SettingsScreen extends StatelessWidget {
static const String routeName = "/settings";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Settings"),
),
body: Container(
child: Center(
child: Text("Settings Screen"),
)),
);
}
}
Ensure a supported device is connected or emulator/simulator is started
Go to project directory
Use flutter run
command to run
flutter run
It builds and runs app on an available android/ios device