I want to persist Navigation Drawer across all screens. There have been questions on stack over this but my question is little different fo e.g. Persisting AppBar Drawer across all Pages Flutter
I have Navigation Drawer with list of items called A,B and C. On Clicking of A in Navigation Drawer,Screen A opens and respectively same thing for B and C. Now the C screen has a button and on click of that button I am going to screen D, now though the screen D shows the Navigation Drawer icon, the drawer never opens up. I tried printing a statement in the method where drawer is called and the print statement does prints but the drawer never opens. Following is my code
I have a base class whose drawer is as follows
class BaseScreen extends StatefulWidget {
final List<Menu> menuList;
final String userType;
final String userId;
const BaseScreen({Key key, this.menuList, this.userType, this.userId})
: super(key: key);
@override
BaseScreenState createState() {
return new BaseScreenState();
}
}
class BaseScreenState extends State<BaseScreen> {
String screenNameSelected = "A";
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
_getDrawerItemWidget(screenNameSelected),
],
),
drawer: SizedBox(
width: 100,
child: Drawer(
child: ListView.separated(
separatorBuilder: (context, index) => Material(
elevation: 2,
shadowColor: shadow,
child: Divider(
color: white,
),
),
itemBuilder: (BuildContext context, int index) {
return ListTile(
onTap: () {
openScreen(
widget.menuList[index].title,
widget.userId,
MenuList.returnLoginType(widget.userType).toString(),
context);
Navigator.pop(context);
},
title: Padding(
padding: const EdgeInsets.only(top: 8),
child: Image.asset(
widget.menuList[index].image,
width: 35,
height: 35,
),
),
);
},
itemCount: widget.menuList?.length ?? 0,
shrinkWrap: true,
physics: BouncingScrollPhysics(),
),
),
),
);
}
_getDrawerItemWidget(String selectedScreenName) {
switch (selectedScreenName) {
case A:
return A();
case B:
return B();
case C:
return C();
default:
return Container();
}
}
void openScreen(String screenName, String userId, String loginType,
BuildContext context) {
if (screenName.toLowerCase() == "A".toLowerCase()) {
setState(() {
screenNameSelected = "A";
});
} else if (screenName.toLowerCase() == "B".toLowerCase()) {
setState(() {
screenNameSelected = "B";
});
} else if (screenName.toLowerCase() == "C".toLowerCase()) {
setState(() {
screenNameSelected = "C";
});
}
}
}
I have created a custom class for App bar as my app bar is highly customized
class CustomAppBar extends StatelessWidget {
final String subTitleText;
final String subTitleImage;
const CustomAppBar(
{Key key, @required this.subTitleText, @required this.subTitleImage})
: super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SafeArea(
child: Column(
children: <Widget>[
Builder(builder: (context) => customAppBar(context)),
SizedBox(
height: 5.0,
),
subTitleRow(
subTitleText,
subTitleImage,
)
],
),
),
],
);
}
}
Widget subTitleRow(String subtitleText, String subtitleImage) {
.........
}
Widget customAppBar(BuildContext context) {
return Material(
elevation: 5.0,
shadowColor: shadow,
child: SafeArea(
child: Stack(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Image.asset(
"images/toolbar_logo.webp",
width: 80,
height: 50,
),
],
),
IconButton(
icon: Image.asset("images/menu.webp"),
onPressed: () {
Scaffold.of(context).openDrawer();
},
iconSize: 20,
),
],
),
),
);
}
Now my class A,B and C does not have a scaffold but I had provided my class D with a scaffold and I think that is causing the problem. Not providing class D with a Scaffold does not give a proper layout
Code for Class A,B and C is as follows
class A extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ShortBioProvider(
child: Column(
children: <Widget>[
CustomAppBar(
subTitleImage: "images/settings.webp",
subTitleText: SETTINGS.toUpperCase(),
),
SizedBox(
height: 20,
),
SettingsList(),
],
),
);
}
}
B and C are very similar to A.
Now for class D code
class D extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(body: Column(children: <Widget>[
CustomAppBar(
subTitleImage: "images/settings.webp",
subTitleText: D.toUpperCase(),
),
SizedBox(
height: 20,
),
........
],),);
}
}
I have edited the above classes a lot so there may be a missing bracket or semicolon here or there