I am new to Flutter development. And I have been going through multiple tutorials to understand the Bottom Navigation bar.
I have tried these tutorials but I am not able to achieve the requirement that I have. Tutorials I have followed:
- https://codewithandrea.com/articles/multiple-navigators-bottom-navigation-bar/
- https://medium.com/flutter/getting-to-the-bottom-of-navigation-in-flutter-b3e440b9386
- https://medium.com/@theboringdeveloper/common-bottom-navigation-bar-flutter-e3693305d2d
I personally liked the 1st tutorial because there are nested routes.
Information:
I have bottom navigation with 3 tabs: Home, Calendar, Profile.
Home tabs has a screen: Screen2. Calendar has a screen: Screen3. Profile has a screen: Screen4
Problem:
My bottom navigation bar persisting the state of the screen(which is good).
Home screen has a button which opens Screen2. When user clicks, it pushes the Screen2. And when user clicks on Calendar (tab) user sees Calendar screen. Now, user again clicks on Home button(tab), user sees the Screen2. Because It was part of that route(Home). Where he should see Home screen only.
And I just want to reset it. Basically Home screen should push Home screen and pop all the children of Home page. When tabs are switched.
Code:
main.dart
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainScreen(),
);
}
}
main_screen.dart
class MainScreen extends StatefulWidget {
MainScreen({Key key}) : super(key: key);
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
int _selectedIndex = 0;
List<GlobalKey<NavigatorState>> _navigatorKeys = [
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>()
];
List<Widget> _widgetOptions = <Widget>[
HomePage(),
CalendarPage(),
ProfilePage(),
];
Map<String, WidgetBuilder> _routeBuilders(BuildContext context, int index) {
return {
'/': (context) {
return [
HomePage(),
CalendarPage(),
ProfilePage(),
].elementAt(index);
},
};
}
Widget _buildOffstageNavigator(int index) {
var routeBuilders = _routeBuilders(context, index);
return Offstage(
offstage: _selectedIndex != index,
child: Navigator(
key: _navigatorKeys[index],
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => routeBuilders[routeSettings.name](context),
);
},
),
);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
final isFirstRouteInCurrentTab =
!await _navigatorKeys[_selectedIndex].currentState.maybePop();
// let system handle back button if we're on the first route
return isFirstRouteInCurrentTab;
},
child: Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Stack(
children: [
_buildOffstageNavigator(0),
_buildOffstageNavigator(1),
_buildOffstageNavigator(2),
],
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
showSelectedLabels: false,
showUnselectedLabels: false,
items: [
BottomNavigationBarItem(
icon: Icon(
Feather.home,
color: Colors.grey[300],
),
label: 'HOME',
activeIcon: Icon(
Feather.home,
color: Colors.purple[300],
),
),
BottomNavigationBarItem(
icon: Icon(
FontAwesome.calendar,
color: Colors.grey[300],
),
label: 'CALENDAR',
activeIcon: Icon(
FontAwesome.calendar,
color: Colors.purple[300],
),
),
BottomNavigationBarItem(
icon: Icon(
EvilIcons.user,
color: Colors.grey[300],
size: 36,
),
label: 'PROFILE',
activeIcon: Icon(
EvilIcons.user,
color: Colors.purple[300],
size: 36,
),
),
],
onTap: (index) {
setState(() {
_selectedIndex = index;
});
},
),
),
);
}
}
home_page.dart
class HomePage extends StatefulWidget {
HomePage();
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.lightBlueAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
child: Text(
'Screen 1',
style: TextStyle(color: Colors.white, fontSize: 20),
),
margin: EdgeInsets.all(16),
),
FlatButton(
onPressed: () {
// Navigator.push(context, MaterialPageRoute(
// builder: (context) => Screen2()
// ));
Navigator.push(context, PageRouteBuilder(pageBuilder: (_,__,___) => Screen2()));
},
child: Text('Go to next screen'),
color: Colors.white,
),
],
));
}
}
calendar_page.dart
class CalendarPage extends StatefulWidget {
CalendarPage({Key key}) : super(key: key);
@override
_CalendarPageState createState() => _CalendarPageState();
}
class _CalendarPageState extends State<CalendarPage> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Center(
child: FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => Screen3()
));
},
child: Text('Go to next screen'),
color: Colors.white,
),
),
);
}
}
I would really appreciate if anyone could point me to direction. Thanks in Advance.
Requirement: There are tabs, each tab will respective screens(ScreenX-> ScreenY-> ScreenN). And when tab is switched it should pop all the children of the tabs. I hope this understandable(Sorry, my English is not good).
What am I missing here?