Bottom navigation is a common design pattern for placing top-level and frequently-used actions. Let us implement it using Flutter.
The child screens
We will need three screen-widgets for showing different screens for each tab. Create simple stateful widgets in three files, as below for Home, Search and Profile screens.
home_screen.dart
class HomeScreen extends StatefulWidget { @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { return Container(); } }
class SearchScreen extends StatefulWidget { @override _SearchScreenState createState() => _SearchScreenState(); } class _SearchScreenState extends State<SearchScreen> { @override Widget build(BuildContext context) { return Container(); } }
class ProfileScreen extends StatefulWidget { @override _ProfileScreenState createState() => _ProfileScreenState(); } class _ProfileScreenState extends State<ProfileScreen> { @override Widget build(BuildContext context) { return Container(); } }
The parent screen
Now let us create a stateful widget for the main screen that will hold the tabbar and allow switching between tabs, and display the selected screen.
tabbar_screen.dart
class TabBarScreen extends StatefulWidget { @override _TabBarScreenState createState() => _TabBarScreenState(); } class _TabBarScreenState extends State<TabBarScreen> {
return Container(); } }
Declare a variable to store the list of our child screens in a list, and another to hold the current active screen index.
List<Widget> pageList = List<Widget>(); int _currentIndex = 0;
Initialise the state by adding the screens to the list.
@override void initState() { pageList.add(HomeScreen()); pageList.add(SearchScreen()); pageList.add(ProfileScreen()); super.initState(); }
Finally, we modify the build method to return an indexed stack, with bottom navigation bar and a view that shows the currently selected screen.
We are using an IndexedStack so that the state is preserved, that is, the screens are not recreated each time it is changed. Alternatively, this can also be achieved by using a PageView along with AutomaticKeepAliveClientMixin.
@override Widget build(BuildContext context) { return Scaffold( body: IndexedStack( index: _currentIndex, children: pageList, ), bottomNavigationBar: BottomNavigationBar( onTap: onTabTapped, currentIndex: _currentIndex, type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem( icon: new Icon(Icons.home), title: new Text( 'HOME', ), ), BottomNavigationBarItem( icon: new Icon(Icons.search), title: new Text( 'SEARCH', ), ), BottomNavigationBarItem( icon: Icon(Icons.person), title: Text( 'PROFILE', ) ), ], ), ); }
Implement the method that we called above, for onTap event of BottomNavigationBar
void onTabTapped(int index) { setState(() { _currentIndex = index; }); }
Run the app, now you can see a screen with three tabs on the bottom, and the view is loaded according to the selected tab.
…
Leave A Comment