Flutter / Examples / Drawer Menu
Drawer Menu
-
Steps
STEP 1. create lib/widget/navigation_drawer_widget.dart
import 'package:flutter/material.dart'; class NavigationDrawerWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Drawer( ); } } STEP 2. call navigation_drawer_widget in main.dart
import 'package:flutter/material.dart'; Future main() async { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) => MaterialApp( title: 'Navigation Drawer', home: MainPage(), ); } class MainPage extends StatefulWidget { @override _MainPageState createState() => _MainPageState(); } class _MainPageState extends State { @override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text(MyApp.title), ), ); } To show drawer menu icon , add drawer: NavigationDrawerWidget() in _MainPageState
import 'package:navigation_drawer_example/widget/navigation_drawer_widget.dart'; ... ... class _MainPageState extends State { @override Widget build(BuildContext context) => Scaffold( drawer: NavigationDrawerWidget(), appBar: AppBar( title: Text(MyApp.title), ), ); } STEP 4: add items to drawer menu
in navigation_drawer_widget.dart
Widget build(BuildContext context) { final name = 'Sarah Abs'; final email = 'sarah@abs.com'; return Drawer( child: Container( color: Color.fromRGBO(50, 75, 205, 1), child: ListView( children: [ buildMenuItem( text: 'People', icon: Icons.people, onClicked: () => selectedItem(context, 0), ) ], ), ), ); } menu item function
Widget buildMenuItem({ required String text, required IconData icon, VoidCallback? onClicked, }) { final color = Colors.white; final hoverColor = Colors.white70; return ListTile( leading: Icon(icon, color: color), title: Text(text, style: TextStyle(color: color)), hoverColor: hoverColor, onTap: onClicked, ); } Click event
void selectedItem(BuildContext context, int index) { Navigator.of(context).pop(); switch (index) { case 0: Navigator.of(context).push(MaterialPageRoute( builder: (context) => PeoplePage(), )); break; case 1: Navigator.of(context).push(MaterialPageRoute( builder: (context) => FavouritesPage(), )); break; } } Note that Navigator.of(context).push() for navigativing to another page STEP 6: navigate to another page
page/favourites_page.dart
import 'package:flutter/material.dart'; class FavouritesPage extends StatelessWidget { @override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('Favourites'), centerTitle: true, backgroundColor: Colors.red, ), ); } page/people_page.dart
import 'package:flutter/material.dart'; class PeoplePage extends StatelessWidget { @override Widget build(BuildContext context) => Scaffold( //drawer: NavigationDrawerWidget(), appBar: AppBar( title: Text('People'), centerTitle: true, backgroundColor: Colors.green, ), ); } use above pages in widget/navigation_drawer_widget.dart
import 'package:flutter/material.dart'; import 'package:navigation_drawer_example/page/favourites_page.dart'; import 'package:navigation_drawer_example/page/people_page.dart'; ... .... Navigator.of(context).push(MaterialPageRoute( builder: (context) => PeoplePage(), )); STEP 7 : styling
padding
padding:EdgeInsets.symmetric(horizontal: 20); color
color: Color.fromRGBO(50, 75, 205, 1), line height between items
const SizedBox(height: 16), divider or line separator between the items
Divider(color: Colors.white70), STEP8: add header
create function
Widget buildHeader({ required String urlImage, required String name, required String email, required VoidCallback onClicked, }) => InkWell( onTap: onClicked, child: Container( padding: padding.add(EdgeInsets.symmetric(vertical: 40)), child: Row( children: [ CircleAvatar(radius: 30, backgroundImage: NetworkImage(urlImage)), SizedBox(width: 20), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, style: TextStyle(fontSize: 20, color: Colors.white), ), const SizedBox(height: 4), Text( email, style: TextStyle(fontSize: 14, color: Colors.white), ), ], ), Spacer(), CircleAvatar( radius: 24, backgroundColor: Color.fromRGBO(30, 60, 168, 1), child: Icon(Icons.add_comment_outlined, color: Colors.white), ) ], ), ), ); call buildHeader() in ListView
return Drawer( child: Material( color: Color.fromRGBO(50, 75, 205, 1), child: ListView( children: [ buildHeader( urlImage: urlImage, name: name, email: email, onClicked: () => Navigator.of(context).push(MaterialPageRoute( builder: (context) => UserPage( name: 'Sarah Abs', urlImage: urlImage, ), )), ), ... .... STEP 9: add search panel
create function
Widget buildSearchField() { final color = Colors.white; return TextField( style: TextStyle(color: color), decoration: InputDecoration( contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), hintText: 'Search', hintStyle: TextStyle(color: color), prefixIcon: Icon(Icons.search, color: color), filled: true, fillColor: Colors.white12, enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: color.withOpacity(0.7)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: color.withOpacity(0.7)), ), ), ); } call buildSearchField(), in listView
Complete code is givenimport 'package:flutter/material.dart'; import 'package:navigation_drawer_example/page/favourites_page.dart'; import 'package:navigation_drawer_example/page/people_page.dart'; import 'package:navigation_drawer_example/page/user_page.dart'; class NavigationDrawerWidget extends StatelessWidget { final padding = EdgeInsets.symmetric(horizontal: 20); @override Widget build(BuildContext context) { final name = 'Sarah Abs'; final email = 'sarah@abs.com'; final urlImage = 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80'; return Drawer( child: Material( color: Color.fromRGBO(50, 75, 205, 1), child: ListView( children: [ buildHeader( urlImage: urlImage, name: name, email: email, onClicked: () => Navigator.of(context).push(MaterialPageRoute( builder: (context) => UserPage( name: 'Sarah Abs', urlImage: urlImage, ), )), ), Container( padding: padding, child: Column( children: [ const SizedBox(height: 12), buildSearchField(), const SizedBox(height: 24), buildMenuItem( text: 'People', icon: Icons.people, onClicked: () => selectedItem(context, 0), ), const SizedBox(height: 16), buildMenuItem( text: 'Favourites', icon: Icons.favorite_border, onClicked: () => selectedItem(context, 1), ), const SizedBox(height: 16), buildMenuItem( text: 'Workflow', icon: Icons.workspaces_outline, onClicked: () => selectedItem(context, 2), ), const SizedBox(height: 16), buildMenuItem( text: 'Updates', icon: Icons.update, onClicked: () => selectedItem(context, 3), ), const SizedBox(height: 24), Divider(color: Colors.white70), const SizedBox(height: 24), buildMenuItem( text: 'Plugins', icon: Icons.account_tree_outlined, onClicked: () => selectedItem(context, 4), ), const SizedBox(height: 16), buildMenuItem( text: 'Notifications', icon: Icons.notifications_outlined, onClicked: () => selectedItem(context, 5), ), ], ), ), ], ), ), ); } Widget buildHeader({ required String urlImage, required String name, required String email, required VoidCallback onClicked, }) => InkWell( onTap: onClicked, child: Container( padding: padding.add(EdgeInsets.symmetric(vertical: 40)), child: Row( children: [ CircleAvatar(radius: 30, backgroundImage: NetworkImage(urlImage)), SizedBox(width: 20), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, style: TextStyle(fontSize: 20, color: Colors.white), ), const SizedBox(height: 4), Text( email, style: TextStyle(fontSize: 14, color: Colors.white), ), ], ), Spacer(), CircleAvatar( radius: 24, backgroundColor: Color.fromRGBO(30, 60, 168, 1), child: Icon(Icons.add_comment_outlined, color: Colors.white), ) ], ), ), ); Widget buildSearchField() { final color = Colors.white; return TextField( style: TextStyle(color: color), decoration: InputDecoration( contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), hintText: 'Search', hintStyle: TextStyle(color: color), prefixIcon: Icon(Icons.search, color: color), filled: true, fillColor: Colors.white12, enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: color.withOpacity(0.7)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide(color: color.withOpacity(0.7)), ), ), ); } Widget buildMenuItem({ required String text, required IconData icon, VoidCallback? onClicked, }) { final color = Colors.white; final hoverColor = Colors.white70; return ListTile( leading: Icon(icon, color: color), title: Text(text, style: TextStyle(color: color)), hoverColor: hoverColor, onTap: onClicked, ); } void selectedItem(BuildContext context, int index) { Navigator.of(context).pop(); switch (index) { case 0: Navigator.of(context).push(MaterialPageRoute( builder: (context) => PeoplePage(), )); break; case 1: Navigator.of(context).push(MaterialPageRoute( builder: (context) => FavouritesPage(), )); break; } } }