I need to develop a navigation drawer in flutter and I'm new to flutter, I am using the following code, and this is creating the menu as expected but the problem is
1.handling screen navigation
2.maintaining state and navigating back to the screen which is previously opened
I am unable to use this code in stateful widget as i need to maintain the state of the navigation drawer
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class ExpansionList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) => EntryItem(
data[index],
),
);
}
}
// Welcome to another flutter tutorial
// In this video we will see how to create a multi-level Expansion List
// First Let's create a class for each row in the Expansion List
class Entry {
final String title;
final List<Entry>
children; // Since this is an expansion list ...children can be another list of entries
Entry(this.title, [this.children = const <Entry>[]]);
}
// This is the entire multi-level list displayed by this app
final List<Entry> data = <Entry>[
Entry(
'Chapter A',
<Entry>[
Entry('Section A0',
// <Entry>[
// Entry('Item A0.1'),
// Entry('Item A0.2'),
// Entry('Item A0.3'),
// ],
),
Entry('Section A1'),
Entry('Section A2'),
],
),
// Second Row
Entry('Chapter B', <Entry>[
Entry('Section B0'),
Entry('Section B1'),
]),
Entry(
'Chapter C',
<Entry>[
Entry('Section C0'),
Entry('Section C1'),
Entry(
'Section C2',
<Entry>[
Entry('Item C2.0'),
Entry('Item C2.1'),
Entry('Item C2.2'),
Entry('Item C2.3'),
],
)
],
),
];
// Create the Widget for the row
class EntryItem extends StatelessWidget {
const EntryItem(this.entry);
final Entry entry;
// This function recursively creates the multi-level list rows.
Widget _buildTiles(Entry root) {
if (root.children.isEmpty) {
return ListTile(
title: Text(root.title),
onTap: (){
Fluttertoast.showToast(msg: root.title);
_getDrawerItemWidget(root.title);
},
);
}
return ExpansionTile(
key: PageStorageKey<Entry>(root),
title: Text(root.title),
children: root.children.map<Widget>(_buildTiles).toList(),
);
}
@override
Widget build(BuildContext context) {
return Container(
child: _buildTiles(entry));
}
_getDrawerItemWidget(String screenName) {
switch (screenName) {
case "Section A0":
return new ThirdScreen();
case "Section A1":
return new SecondScreen();
case "Section A2":
return new ThirdScreen();
default:
return new Text("Error");
}
}
}
Basically I am an android app developer I'm looking forward to implement the following concept like sigle activity with navigation drawer and handling multiple fragments in flutter
Please help me to achieve the requirement
Any source code suggestions or fully implemented code is helpful for my need
Finally, No one answered here and I work around and find the solution for my problem
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class NavDrawer extends StatefulWidget with PreferredSizeWidget {
@override
State<StatefulWidget> createState() {
return new NavDrawerState();
}
@override
// TODO: implement preferredSize
Size get preferredSize => throw UnimplementedError();
}
class NavDrawerState extends State<NavDrawer> {
int _selectedDrawerIndex = 0;
String screenName = "Home";
final ScrollController scroll = ScrollController();
@override
void dispose() {
scroll.dispose();
super.dispose();
}
_getDrawerItemWidget(String pos) {
switch (pos) {
case "Home":
return new HomeScreen();
case "Receiving":
return new FirstScreen();
case "Putaway":
return new SecondScreen();
case "Pallet Transfer":
return new ThirdScreen();
default:
return new Text("Error");
}
}
_onSelectItem(String screen) {
setState(() => screenName = screen);
Navigator.of(context).pop(); // close the drawer
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
// here we display the title corresponding to the fragment
// you can instead choose to have a static title
child: Text(screenName),
context: context,
),
drawer: Drawer(
child: Container(
decoration: AppConstants.customBoxDecoration,
//you can use your own boxdecoration
child: Column(
children: <Widget>[
UserAccountsDrawerHeader(
decoration: AppConstants.customBoxDecoration,
currentAccountPicture: new CircleAvatar(
radius: 60.0,
// backgroundColor: const Color(0xFF778899),
backgroundImage: AssetImage('assets/logo.png'),
),
accountName: new Text("Name"),
accountEmail: new Text("mail")),
Flexible(
child: ListView.builder(
shrinkWrap: true,
controller: scroll,
itemCount: StringConstants.menuList.length,
itemBuilder: (BuildContext context, int index) => buildList(
StringConstants.menuList[index],
))
)
],
),
)),
body: _getDrawerItemWidget(screenName),
);
}
// This function recursively creates the multi-level list rows.
Widget _buildTiles(Entry root) {
if (root.children.isEmpty) {
return ListTile(
leading: Icon(root.icon),
title: Text(
root.title,
style: AppConstants.textStyleNavDrawer,
),
onTap: () {
Fluttertoast.showToast(msg: root.title);
_onSelectItem(root.title);
},
);
}
return ExpansionTile(
key: PageStorageKey<Entry>(root),
maintainState: true,
title: Text(
root.title,
style: AppConstants.textStyleNavDrawer,
),
children: root.children.map<Widget>(_buildTiles).toList(),
);
}
Widget buildList(Entry entry) {
return _buildTiles(entry);
}
}
Custom app bar class
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final Widget child;
final double height;
final BuildContext context;
CustomAppBar(
{required this.child,
this.height = kToolbarHeight,
required this.context});
@override
Size get preferredSize => Size.fromHeight(height);
@override
Widget build(BuildContext context) {
return AppBar(
title: child,
flexibleSpace: Container(
decoration: AppConstants.customBoxDecoration,
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.qr_code_scanner,
color: Colors.white,
),
onPressed: () {
Fluttertoast.showToast(msg: context.toString());
// do something
},
)
],
);
}
}
App constants class
import 'package:flutter/material.dart';
class AppConstants {
static const BoxDecoration customBoxDecoration = BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [CustomColors.iconSplashColor, CustomColors.iconColor]));
// you define your own colors
static const TextStyle textStyleNavDrawer = TextStyle(
color: Colors.white);
}
Try this example if you need a single app bar for different screens