Reputation: 3021
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:
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?
Upvotes: 3
Views: 5227
Reputation: 3021
So the logic is if I move away from Home screen(tab) to any other tab. I should clear the stack(not referring to the widget).
Assuming you are following 1st tutorial.
There are 3 tabs. Home, Calendar and Profile.
Now from Home screen I added "Screen2". So, right now my currentTab is "Home". If I click Calendar tab my selectedTtab is "Calendar".
I will pop everything from my current tab until the first route is met. Once this is done I will set the state.
Code:
void _selectTab(TabItem tabItem) {
if (tabItem == _currentTab) {
_navigatorKeys[tabItem]?.currentState?.popUntil((route) => route.isFirst);
} else {
//! Added logic to Pop everything from Home tab, if any other tab is clicked
if (_currentTab == TabItem.HOME) {
_navigatorKeys[_currentTab]
?.currentState
?.popUntil((route) => route.isFirst);
}
setState(() => _currentTab = tabItem);
}
}
And I am calling this method from Bottom navigation.
bottomNavigationBar: BottomNavigation(
currentTab: _currentTab,
onSelectTab: _selectTab,
),
Hope this helps. Let me know if this is sufficient.
Upvotes: 1