Disable or Hide bottom navigation bar on few screens of the app using DIY NAVIGATOR SOLUTION
I want to disable or hide the bottom navigation bar on few screens of the app using DIY NAVIGATOR SOLUTION. How can I achieve it?
Like if I go inside AllCtgView (It is the class that I'm opening inside TabNavigator upon clicking a button inside the bottom navigation bar), I want the navigation bar to hide whenever any screen inside the AllCtgView class showed up.
MyApp Class
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BaseHomeView(),
);
}
}
BaseHomeView class
/////////////////////////////////////////////////////////////////////////////
/// DIY NAVIGATOR SOLUTION
////////////////////////////////////////////////////////////////////////////
class BaseHomeView extends StatefulWidget {
@override
State<StatefulWidget> createState() => BaseHomeViewState();
}
class BaseHomeViewState extends State<BaseHomeView> {
String _currentPage = "Page1";
List<String> pageKeys = ["Page1", "Page2", "Page3", "Page4", "Page5"];
Map<String, GlobalKey<NavigatorState>> _navigatorKeys = {
"Page1": GlobalKey<NavigatorState>(),
"Page2": GlobalKey<NavigatorState>(),
"Page3": GlobalKey<NavigatorState>(),
"Page4": GlobalKey<NavigatorState>(),
"Page5": GlobalKey<NavigatorState>(),
};
int _selectedIndex = 0;
void _selectTab(String tabItem, int index) {
if (tabItem == _currentPage) {
_navigatorKeys[tabItem].currentState.popUntil((route) => route.isFirst);
} else {
setState(() {
_currentPage = pageKeys[index];
_selectedIndex = index;
});
}
}
@override
Widget build(BuildContext context) {
final _deviceSize = MediaQuery.of(context).size;
return WillPopScope(
onWillPop: () async {
final isFirstRouteInCurrentTab =
!await _navigatorKeys[_currentPage].currentState.maybePop();
if (isFirstRouteInCurrentTab) {
if (_currentPage != "Page1") {
_selectTab("Page1", 1);
return false;
}
}
// let system handle back button if we're on the first route
return isFirstRouteInCurrentTab;
},
child: Scaffold(
body: Stack(children: <Widget>[
_buildOffstageNavigator("Page1"),
_buildOffstageNavigator("Page2"),
_buildOffstageNavigator("Page3"),
_buildOffstageNavigator("Page4"),
_buildOffstageNavigator("Page5"),
]),
bottomNavigationBar: CurvedNavigationBar(
color: Colors.white,
backgroundColor: colorBlueLightShade,
buttonBackgroundColor: Colors.white,
onTap: (int index) {
_selectTab(pageKeys[index], index);
},
index: _selectedIndex,
items: <Widget>[
Icon(FontAwesomeIcons.bars, size: _deviceSize.height * 0.02),
Icon(FontAwesomeIcons.bars, size: _deviceSize.height * 0.02),
Icon(FontAwesomeIcons.heart, size: _deviceSize.height * 0.02),
Icon(FontAwesomeIcons.shoppingCart,
size: _deviceSize.height * 0.02),
Icon(FontAwesomeIcons.bars, size: _deviceSize.height * 0.02),
],
// type: BottomNavigationBarType.fixed,
),
),
);
}
Widget _buildOffstageNavigator(String tabItem) {
return Offstage(
offstage: _currentPage != tabItem,
child: TabNavigator(
navigatorKey: _navigatorKeys[tabItem],
tabItem: tabItem,
),
);
}
}
TabNavigator class below
class TabNavigatorRoutes {
static const String root = '/';
static const String detail = '/detail';
}
class TabNavigator extends StatelessWidget {
TabNavigator({this.navigatorKey, this.tabItem});
final GlobalKey<NavigatorState> navigatorKey;
final String tabItem;
@override
Widget build(BuildContext context) {
Widget child;
if (tabItem == "Page1")
child = HomeView();
else if (tabItem == "Page2")
child = AllCtgView();
else if (tabItem == "Page3")
child = FavouriteProductsView();
else if (tabItem == "Page4")
child = CartView();
else if (tabItem == "Page5") child = HomeView();
return Navigator(
key: navigatorKey,
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(builder: (context) => child);
},
);
}
}
I am guessing you mean after accessing the AllCtgView(), all the pages you access after it should have no bottom nav bar.
You want to do something like for every place that you navigate in that page: Navigator.of(context, rootNavigator: true).pushNamed("/route"); and Navigator.of(context, rootNavigator: true).push(MaterialPageRoute(builder: (context) => SecondRoute()),);
The key to having full screen back is saying that "rootNavigator:true"
I am guessing you mean after accessing the AllCtgView(), all the pages you access after it should have no bottom nav bar.
You want to do something like for every place that you navigate in that page: Navigator.of(context, rootNavigator: true).pushNamed("/route"); and Navigator.of(context, rootNavigator: true).push(MaterialPageRoute(builder: (context) => SecondRoute()),);
The key to having full screen back is saying that "rootNavigator:true"
But where to do it though? Should I do it in TabNavigator class inside the onGenerateRoute? Or somewhere else? Can you please edit the part of the code where I have to write it and share it with me, please
Are you trying to do this after you get to the AllCtgView() or are you trying to do that on the base layer of the bottom nav bar.
Just a little confused. In my head, I am thinking after you navigate to the AllCtgView(),page, you can still see the bottom nav bar but when you click anything inside that particular page, it disappears. Is this correct?
Are you trying to do this after you get to the AllCtgView() or are you trying to do that on the base layer of the bottom nav bar.
Just a little confused. In my head, I am thinking after you navigate to the AllCtgView(),page, you can still see the bottom nav bar but when you click anything inside that particular page, it disappears. Is this correct?
Brother forget about AllCtgView(). Let me tell you what I'm actually trying to do. I understand that using the above method we will be able to show the bottom navigation bar to all the screens of the app.
There are almost 30 screens in my app. But on few screens like the login screen, cartview screen, orderview screen, and a couple of others, I don't want to show the bottom navigation bar there. I just want to hide it on these specific screens. As I proceed to pass any of these screens, the bottom navigation bar should re-appear.
I'm a bad explainer. I hope you got my point
@Kickbykick Brother can you help me with that? i'm still struggling
I apologize for the later reply,
So for the login screen, this screen is meant to come before your main page. What you should do for this screen is to not have it be under the scaffold that has the bottom navigation bar.
What I would usually do is have a boolean that checks if the user is authenticated already
if(authenticated){
return LoginScreen();
} else {
return HomeScreen(); // This screen now starts the navigation bar
}
For the CartView and the OrderView screen, anytime a user clicks a button on those screens, you want to do this -> Navigator.of(context, rootNavigator: true).push(MaterialPageRoute(builder: (context) => CartView()),);
And then when the user wants to come out of those screens, if you want your bottom navigation bar back, the only way I can think of is Navigator.pop(context); then Push the new page on top of it. so:
Navigator.pop(context)
Navigator.of(context).push(MaterialPageRoute(builder: (context) => BackToMenu()),)
or if you are using named routes
Navigator.popAndPushNamed(context, '/screen4');
I am guessing you mean after accessing the AllCtgView(), all the pages you access after it should have no bottom nav bar.
You want to do something like for every place that you navigate in that page: Navigator.of(context, rootNavigator: true).pushNamed("/route"); and Navigator.of(context, rootNavigator: true).push(MaterialPageRoute(builder: (context) => SecondRoute()),);
The key to having full screen back is saying that "rootNavigator:true"
Yes that's worked, Thanks for sharing the most valuable info