Hi, developers I hope you are very well and enjoying the life of Flutter app development easy way. In, this article has explained “how to make a side menu in a Flutter” in easy ways.
Let’s Start
Drawer (side menu)
The Drawer widget(material library import ‘package:flutter/material.dart’ ) takes a child parameter, which is a widget that appears at the top of the menu, usually as a title or header. The child parameter is often a DrawerHeader widget, which provides a space to display a title or logo.
Code
(new) Drawer Drawer({
Key? key,
Color? backgroundColor,
double? elevation,
Color? shadowColor,
Color? surfaceTintColor,
ShapeBorder? shape,
double? width,
Widget? child,
String? semanticLabel,
})
The Drawer widget also takes a ListView or Column of ListTile widgets as its main content. Each ListTile represents a menu item, and the onTap property of the ListTile can be used to handle user interaction when the menu item is selected.
To make a side menu in a Flutter app, you can use the Drawer widget as follows:
- Add the Scaffold widget to your screen’s build method, which will provide the basic structure for your screen.
- Inside the Scaffold, add an AppBar widget to the appBar property. This will create the app bar at the top of the screen.
- Inside the Scaffold, add a Drawer widget to the drawer property. This will create the side menu.
- Inside the Drawer, add a Column widget with your menu items as ListTile widgets.
- In the onTap property of each ListTile, add the code to navigate to the corresponding screen or perform the appropriate action.
- UserAccountsDrawerHeader – show the user info on the header of the side menu.
Menu Top Bar (DrawerHeader)
Code(DrawerHeader)
Container(
child: UserAccountsDrawerHeader(
decoration: BoxDecoration(
color: WidgetColors.mainHeaderColor,
),
accountName: InkWell(
onTap: () {},
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: myAccountName ?? 'NA',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
TextSpan(text: ' '),
],
),
),
),
accountEmail: Text(myGroupType),
currentAccountPicture: InkWell(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => EditProfileImage(
nameInfo: myAccountName.toString(),
)));
},
child: Stack(
children: <Widget>[
Container(
width: 250,
height: 250,
child: CircleAvatar(
backgroundColor: AppTheme.mainColor,
radius: 43,
child: ClipOval(
child: FadeInImage(
fadeInDuration: const Duration(milliseconds: 500),
placeholder:
const AssetImage('assets/images/userL.png'),
image: vThumbImage == null
? NetworkImage(
"https://img.icons8.com/fluency/48/null/no-image.png")
: NetworkImage(vThumbImage!),
imageErrorBuilder: (context, error, stackTrace) {
return Container(
child: Image.asset("assets/images/userL.png"));
},
fit: BoxFit.cover,
height: 70,
width: 70,
),
),
),
),
Positioned(
bottom: 1,
right: 1,
child: Container(
height: 35,
width: 35,
child: InkWell(
child: const Icon(
Icons.add_a_photo,
size: 15.0,
color: Color(0xFF404040),
),
),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.all(Radius.circular(20))),
))
],
),
),
)),
Final Code
Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
//------------user image section and other deatils //
Container(
child: UserAccountsDrawerHeader(
decoration: BoxDecoration(
color: WidgetColors.mainHeaderColor,
),
accountName: InkWell(
onTap: () {},
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: myAccountName ?? 'NA',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
),
),
TextSpan(text: ' '),
],
),
),
),
accountEmail: Text('yourEmail@gmail.com'),
currentAccountPicture: InkWell(
onTap: () {
//-your action
},
child: Stack(
children: <Widget>[
Container(
width: 250,
height: 250,
child: CircleAvatar(
backgroundColor: AppTheme.mainColor,
radius: 43,
child: ClipOval(
child: FadeInImage(
fadeInDuration: const Duration(milliseconds: 500),
placeholder:
const AssetImage('assets/images/userL.png'),
image: vThumbImage == null
? NetworkImage(
"https:xxxx/no-image.png")
: NetworkImage(vThumbImage!),
imageErrorBuilder: (context, error, stackTrace) {
return Container(
child: Image.asset("assets/images/userL.png"));
},
fit: BoxFit.cover,
height: 70,
width: 70,
),
),
),
),
Positioned(
bottom: 1,
right: 1,
child: Container(
height: 35,
width: 35,
child: InkWell(
// onTap: _onAlertPress,
child: const Icon(
Icons.add_a_photo,
size: 15.0,
color: Color(0xFF404040),
),
),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.all(Radius.circular(20))),
))
],
),
),
)),
//--------menu list ------------------//
ListTile(
leading: Icon(Icons.home),
title: Text(
'side_MenuHome'.tr,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () => selectedItem(context, 0),
),
ListTile(
leading: Icon(Icons.history_rounded),
title: Text(
'side_MenuOrderHistory'.tr,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () => selectedItem(context, 1),
),
ListTile(
leading: Icon(Icons.payment),
title: Text(
'side_MenuPaymentHistory'.tr,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () => selectedItem(context, 2),
),
ListTile(
leading: Icon(
Icons.settings,
color: Colors.black54,
),
title: Text(
'side_MenuSettings'.tr,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () => selectedItem(context, 3),
),
ListTile(
leading: Image.asset(
"assets/images/location.png",
width: 25,
height: 25,
fit: BoxFit.fill,
color: Colors.black54,
),
title: Text(
'side_MenuChooseLocation'.tr,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () => selectedItem(context, 4),
),
ListTile(
leading: Image.asset(
"assets/images/complain.png",
width: 25,
height: 25,
fit: BoxFit.fill,
color: Colors.black54,
),
title: Text(
"Support",
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () => selectedItem(context, 5),
),
ListTile(
leading: Image.asset(
"assets/images/feedback.png",
width: 25,
height: 25,
fit: BoxFit.fill,
color: Colors.black54,
),
title: Text(
"Feedback",
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () => selectedItem(context, 6),
),
ListTile(
leading: Icon(Icons.update),
title: Text(
'side_MenuUpdate'.tr,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
letterSpacing: 0,
),
),
onTap: () {
Fluttertoast.showToast(
msg: "Currently no updates available!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: AppTheme.mainTextColor,
textColor: Colors.white,
fontSize: 16.0);
print("update Click");
},
),
new Divider(
color: Colors.black38,
),
ListTile(
leading: Image.asset(
"assets/images/logout.png",
width: 25,
height: 25,
fit: BoxFit.fill,
color: Colors.black54,
),
title: Text('side_MenuLogout'.tr),
onTap: () async {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Logout'),
content: Text('side_MenuLogoutMessage'.tr),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(
'side_MenuLogoutNo'.tr,
style: TextStyle(color: Colors.red),
)),
TextButton(
onPressed: () async {
SharedPreferences prefs =
await SharedPreferences.getInstance();
var groupId = prefs.getString('groupId') ?? '';
var userId = prefs.getString('userId') ?? '';
var password = prefs.getString('password') ?? '';
await prefs.remove("accountId");
await prefs.remove("AccountName");
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
LoginNewPro(groupId, userId, password)),
ModalRoute.withName('/'));
},
child: Text(
'side_MenuLogoutYes'.tr,
style: TextStyle(color: Colors.red),
),
),
],
);
});
},
),
//----------------------end code-------------------//
],
),
);
}
When the user taps on a menu item, we navigate to the corresponding screen using the Navigator widget. We use the pushReplacement method to replace the current screen with the new screen and pop the previous screen.
dart: Function (selectedItem)
void selectedItem(BuildContext context, int index) {
// Navigator.of(context).pop();
print(index);
switch (index) {
case 0:
Navigator.pushReplacementNamed(context, "/home");
break;
case 1:
Navigator.pushReplacementNamed(context, "/profile");
break;
case 2:
Navigator.pushReplacementNamed(
context, "/marketOrderHistory");
break;
case 3:
Navigator.pushReplacementNamed(context, "/paymenthistory");
break;
case 4:
Navigator.pushReplacementNamed(context, "/paymentdeatils");
break;
case 5:
Navigator.pushReplacementNamed(context, "/settings");
break;
case 6:
Navigator.pushReplacementNamed(context, "/chooseLocation");
break;
case 7:
Navigator.pushReplacementNamed(context, "/feedback");
break;
case 8:
Navigator.pushReplacementNamed(context, "/contactus");
break;
}
}
Conclusion
So, we learn how to make a side menu in Flutter, Has been done side menu in a simple way. This above example helps your next project to bind and create fast and enjoy if any issues please comment and feel free to contact us any time.