Flutter Bottom Navigation Bar: A Complete Guide
Bottom navigation bars are a staple in mobile app design, providing a simple and intuitive way for users to navigate through different screens. In Flutter, the BottomNavigationBar widget makes it easy to create smooth, visually appealing bottom navigation. This guide will cover everything you need to know to create and customise bottom navigation bars in Flutter, from setting up the widget to managing navigation state and best practices.

1. What is a Bottom Navigation Bar in Flutter?
A Bottom Navigation Bar is a widget in Flutter that enables users to switch between top-level views with ease. It typically appears at the bottom of the screen and contains icons or text labels to represent each screen or feature. It’s a great choice for apps with 3-5 main sections.
Benefits of Bottom Navigation Bars
- Easy Navigation: Allows users to switch between screens easily.
- Increased Engagement: Helps organize primary sections for quick access.
- Intuitive UI: A familiar design element for mobile users, improving usability.
2. Setting Up a Basic Bottom Navigation Bar
In Flutter, you can create a bottom navigation bar by using the BottomNavigationBar widget, which is typically used within a Scaffold widget.
Basic Example
Here’s a quick example of setting up a bottom navigation bar with three tabs: Home, Search, and Profile.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BottomNavExample(),
);
}
}
class BottomNavExample extends StatefulWidget {
@override
_BottomNavExampleState createState() => _BottomNavExampleState();
}
class _BottomNavExampleState extends State<BottomNavExample> {
int _selectedIndex = 0;
static const List<Widget> _pages = <Widget>[
Center(child: Text('Home')),
Center(child: Text('Search')),
Center(child: Text('Profile')),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Bottom Navigation Bar')),
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
onTap: _onItemTapped,
),
);
}
}
Explanation
- _selectedIndex: Tracks the currently selected tab.
- _onItemTapped: Updates
_selectedIndex
to navigate between tabs. - BottomNavigationBar: Contains three
BottomNavigationBarItem
widgets for Home, Search, and Profile.
3. Customizing the Bottom Navigation Bar
Flutter’s BottomNavigationBar widget is highly customizable. You can adjust colors, icons, text styles, and animations to match your app’s theme.
Customizing Colors and Text Style
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.purple,
unselectedItemColor: Colors.grey,
selectedFontSize: 16,
unselectedFontSize: 14,
backgroundColor: Colors.white,
onTap: _onItemTapped,
),
Explanation
- selectedItemColor and unselectedItemColor allow you to set custom colors for selected and unselected icons.
- selectedFontSize and unselectedFontSize adjust the text size.
Adding Badges and Custom Icons
Adding notification badges or custom icons is a popular customization. Use packages like badges
to easily add a badge to icons.
4. Managing Navigation State with Bottom Navigation
To keep track of the current page, using a combination of setState
and indexed pages (such as ListView) is effective for simple navigation. However, if your app requires persistent state, you may want to use IndexedStack
.
Example Using IndexedStack
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BottomNavWithIndexedStack(),
);
}
}
class BottomNavWithIndexedStack extends StatefulWidget {
@override
_BottomNavWithIndexedStackState createState() => _BottomNavWithIndexedStackState();
}
class _BottomNavWithIndexedStackState extends State<BottomNavWithIndexedStack> {
int _selectedIndex = 0;
final List<Widget> _pages = <Widget>[
HomeScreen(),
SearchScreen(),
ProfileScreen(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Bottom Navigation with IndexedStack')),
body: IndexedStack(
index: _selectedIndex,
children: _pages,
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
onTap: _onItemTapped,
),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Home Screen'));
}
}
class SearchScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Search Screen'));
}
}
class ProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Profile Screen'));
}
}
Explanation
- IndexedStack: Keeps all screens in memory, maintaining their states.
- _onItemTapped: Manages tab selection and updates the
IndexedStack
index.
5. Using Packages for Advanced Bottom Navigation Bars
For more advanced features, you can use packages like curved_navigation_bar
, persistent_bottom_nav_bar
, or bottom_navy_bar
for additional customization options, such as curved or animated navigation bars.
6. Best Practices for Bottom Navigation Bars
- Limit Tabs to 3-5: Keep navigation bars simple with 3-5 items to avoid clutter.
- Use Descriptive Labels: Ensure each item has a clear label that aligns with its function.
- Provide Visual Feedback: Use color changes or animations to indicate the selected item.
- Persistent State for Performance: If your app requires persistent screen states, use
IndexedStack
for smoother navigation.
Conclusion
Bottom Navigation Bars in Flutter provide an intuitive way to organize primary app sections for easy access. With options to customize colors, icons, and layout, you can design a bottom navigation bar that aligns with your app’s aesthetic while ensuring smooth, responsive navigation. By following best practices and understanding the nuances of Flutter’s navigation features, you can create an optimal user experience.
This guide serves as a foundation for creating and customising bottom navigation bars in Flutter, helping you create a polished, user-friendly mobile app.


Explore Other Flutter Topics…
- Introduction to Flutter and Dart
- Why choose Flutter
- Installing Flutter On Your Windows Mac And Linux System
- Your first Flutter app
- Flutter project structure
- Building blocks of Flutter
- Stateful vs. Stateless Widgets Explained
- Flutter layout system
- Flutter text widget
- Creating Buttons in Flutter: ElevatedButton, TextButton, and IconButton
- Handling User Input with Flutter Forms
- Container class in Flutter
- Flutter Navigation
- Flutter – Pass Data One Screen To Another Screen
- Managing Device Orientation in Flutter
- Stateful widget lifecycle in Flutter
- Future of Flutter
- Flutter Themes
- Flutter Animations
- Flutter AppBar Customization
- ListView in Flutter
- Flutter GridView
- Flutter Expanded Widget
- Flutter BottomNavigation Bar
- Floating Action Button
- Drawer Widgets in Flutter
- Form Validation in Flutter
- Flutter TextField
- Adding AdMob ads to a Flutter app
- Building Flutter Web & Desktop Applications
- What is Async and Await in Flutter
- HTTP requests in Flutter
- Parsing JSON in Flutter
- Tinder-Style Swipe Cards in Flutter
- Flutter Tic Tac Toe Game Tutorial
- Flutter Login UI Tutorial
- Flutter Card Widget Tutorial
- Flutter music player app tutorial
- Flutter introduction screens
- Shared Preferences in Flutter
- SQLite Database in Flutter
- Firebase Authentication in Flutter
- Firebase Firestore in Flutter
- Push Notifications in Flutter
- Handling File Uploads in Flutter
- Responsive Design in Flutter
- Provider in Flutter
- Riverpod in Flutter
- Flutter BLoC Pattern Tutorial