Navigation Bar in Flutter
Implement modern, functional navigation bars in your apps
Download Complete ExamplesWhat is Navigation Bar?
Navigation Bar (also known as Bottom Navigation Bar) is a fundamental widget in Flutter that enables navigation between a mobile application's main sections.
Types of Navigation Bars
Basic Implementation
Scaffold with BottomNavigationBar
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Navigation Bar Example',
theme: ThemeData(primarySwatch: Colors.blue),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _selectedIndex = 0;
static const List<Widget> _pages = [
HomePage(),
SearchPage(),
ProfilePage(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Mi App')),
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Find',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
],
),
);
}
}
Main Properties
items
List of navigation elements
Type: List<BottomNavigationBarItem>
Required: Yes
currentIndex
Index of the selected item
Type: int
Required: Yes
onTap
Function called when an item is tapped
Type: ValueChanged<int>
Required: Yes
backgroundColor
The bar's background color
Type: Color
Default: Theme.bottomAppBarColor
selectedItemColor
Color of the selected item
Type: Color
Default: Theme.primaryColor
unselectedItemColor
Color of unselected items
Type: Color
Default: Theme.unselectedWidgetColor
BottomNavigationBarItem
icon
Item icon (required)
icon: Icon(Icons.home)
label
Item text (required)
label: 'Home'
activeIcon
Icon when active (optional)
activeIcon: Icon(Icons.home_filled)
backgroundColor
Background color for the item (optional)
backgroundColor: Colors.blue
Complete Items Example:
BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
activeIcon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search_outlined),
activeIcon: Icon(Icons.search),
label: 'Find',
backgroundColor: Colors.green,
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
activeIcon: Icon(Icons.person),
label: 'Profile',
),
],
)
Visual Examples
1. Navigation Bar Classic
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.shop), label: 'Tienda'),
BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Favorites'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
)
2. Navigation Bar with Custom Colors
BottomNavigationBar(
backgroundColor: Colors.deepPurple,
selectedItemColor: Colors.amber,
unselectedItemColor: Colors.white70,
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.music_note), label: 'Música'),
BottomNavigationBarItem(icon: Icon(Icons.podcasts), label: 'Podcasts'),
BottomNavigationBarItem(icon: Icon(Icons.radio), label: 'Radio'),
],
)
3. Navigation Bar with Badges
// Requiere el package: badges: ^2.0.3BottomNavigationBarItem(
icon: Badge(
badgeContent: Text('3'),
child: Icon(Icons.notifications),
),
label: 'Notificaciones',
)
NavigationBar (Material 3)
Flutter introduces a new Navigation Bar implementation with Material Design 3, more modern and flexible.
NavigationBar with Material 3
NavigationBar(
selectedIndex: _selectedIndex,
onDestinationSelected: (index) => setState(() => _selectedIndex = index),
destinations: const [
NavigationDestination(
icon: Icon(Icons.home_outlined),
selectedIcon: Icon(Icons.home),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.explore_outlined),
selectedIcon: Icon(Icons.explore),
label: 'Explorar',
),
NavigationDestination(
icon: Icon(Icons.person_outlined),
selectedIcon: Icon(Icons.person),
label: 'Profile',
),
],
)
| Feature | BottomNavigationBar | NavigationBar |
|---|---|---|
| Design | Material Design 2 | Material Design 3 |
| Animations | Basic | Smoother |
| Customization | Limited | Extensive |
| Compatibility | All versions | Flutter 3.10+ |
Customizer for Navigation Bar
Application content...
// El código se generará aquí
State Management
1. StatefulWidget Basics
Ideal for simple applications with few screens
class _HomeScreenState extends State<HomeScreen> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: [...],
),
body: _buildPage(_selectedIndex),
);
}
}
2. With Provider (Recommended)
For more complex applications with shared state
class NavigationProvider with ChangeNotifier {
int _currentIndex = 0;
int get currentIndex => _currentIndex;
void changeIndex(int index) {
_currentIndex = index;
notifyListeners();
}
}
// En el widgetConsumer<NavigationProvider>(
builder: (context, provider, child) {
return BottomNavigationBar(
currentIndex: provider.currentIndex,
onTap: (index) => provider.changeIndex(index),
items: [...],
);
},
)
Best Practices
✅ What you SHOULD do
- Use between 3 and 5 items maximum
- Keep labels short and descriptive
- Use recognizable icons
- Implement persistent state between navigations
- Consider using NavigationBar for new apps
❌ What you should NOT do
- Don't use more than 5 items
- Avoid very long labels
- Don't mix different navigation patterns
- Don't forget to handle the state correctly
- Don't use NavigationBar without Material 3
Pro Tip
For an optimal user experience, consider using PageStorage to preserve scroll state and each tab's data as the user navigates between them.
Exercises to Practice
Exercise 1: Music App
Create a music app with navigation between Library, Search and Playlists.
Suggested items: Library, Find, Playlists, Settings
Exercise 2: E-commerce App
Implement an e-commerce app with a cart that shows a badge with the quantity.
Suggested items: Home, Categories, Cart (with badge), Profile
Exercise 3: News App
Create a news app with persistent navigation using Provider.
Suggested items: News, Favorites, Profile, Settings
Common Troubleshooting
❌ The icons don't change color
Solution: Make sure to define selectedItemColor and unselectedItemColor
selectedItemColor: Colors.blue, unselectedItemColor: Colors.grey
❌ The badge doesn't display correctly
Solution: Use the badges package and configure the Badge correctly
Badge(badgeContent: Text('3'), child: Icon(Icons.notifications))
❌ Navigation isn't working
Solution: Verify that currentIndex and onTap are configured
currentIndex: _selectedIndex, onTap: _onItemTapped