Navigation Bar en Flutter
Implementa barras de navegación modernas y funcionales en tus apps
Descargar Ejemplos Completos¿Qué es Navigation Bar?
La Navigation Bar (también conocida como Bottom Navigation Bar) es un widget fundamental en Flutter que permite la navegación entre las secciones principales de una aplicación móvil.
Tipos de Navigation Bars
Implementación Básica
Scaffold con 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: 'Inicio',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Buscar',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Perfil',
),
],
),
);
}
}
Propiedades Principales
items
Lista de elementos de navegación
Tipo: List<BottomNavigationBarItem>
Requerido: Sí
currentIndex
Índice del ítem seleccionado
Tipo: int
Requerido: Sí
onTap
Función llamada al tocar un ítem
Tipo: ValueChanged<int>
Requerido: Sí
backgroundColor
Color de fondo de la barra
Tipo: Color
Por defecto: Theme.bottomAppBarColor
selectedItemColor
Color del ítem seleccionado
Tipo: Color
Por defecto: Theme.primaryColor
unselectedItemColor
Color de los ítems no seleccionados
Tipo: Color
Por defecto: Theme.unselectedWidgetColor
BottomNavigationBarItem
icon
Icono del ítem (requerido)
icon: Icon(Icons.home)
label
Texto del ítem (requerido)
label: 'Inicio'
activeIcon
Icono cuando está activo (opcional)
activeIcon: Icon(Icons.home_filled)
backgroundColor
Color de fondo para el ítem (opcional)
backgroundColor: Colors.blue
Ejemplo Completo de Items:
BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
activeIcon: Icon(Icons.home),
label: 'Inicio',
),
BottomNavigationBarItem(
icon: Icon(Icons.search_outlined),
activeIcon: Icon(Icons.search),
label: 'Buscar',
backgroundColor: Colors.green,
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
activeIcon: Icon(Icons.person),
label: 'Perfil',
),
],
)
Ejemplos Visuales
1. Navigation Bar Clásica
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Inicio'),
BottomNavigationBarItem(icon: Icon(Icons.shop), label: 'Tienda'),
BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Favoritos'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Perfil'),
],
)
2. Navigation Bar con Colores Personalizados
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 con Badges
// Requiere el package: badges: ^2.0.3
BottomNavigationBarItem(
icon: Badge(
badgeContent: Text('3'),
child: Icon(Icons.notifications),
),
label: 'Notificaciones',
)
NavigationBar (Material 3)
Flutter introduce una nueva implementación de Navigation Bar con Material Design 3, más moderna y flexible.
NavigationBar con Material 3
NavigationBar(
selectedIndex: _selectedIndex,
onDestinationSelected: (index) => setState(() => _selectedIndex = index),
destinations: const [
NavigationDestination(
icon: Icon(Icons.home_outlined),
selectedIcon: Icon(Icons.home),
label: 'Inicio',
),
NavigationDestination(
icon: Icon(Icons.explore_outlined),
selectedIcon: Icon(Icons.explore),
label: 'Explorar',
),
NavigationDestination(
icon: Icon(Icons.person_outlined),
selectedIcon: Icon(Icons.person),
label: 'Perfil',
),
],
)
| Característica | BottomNavigationBar | NavigationBar |
|---|---|---|
| Diseño | Material Design 2 | Material Design 3 |
| Animaciones | Básicas | Más fluidas |
| Personalización | Limitada | Extensa |
| Compatibilidad | Todas las versiones | Flutter 3.10+ |
Personalizador de Navigation Bar
Contenido de la aplicación...
// El código se generará aquí
Gestión de Estado
1. StatefulWidget Básico
Ideal para aplicaciones simples con pocas pantallas
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. Con Provider (Recomendado)
Para aplicaciones más complejas con estado compartido
class NavigationProvider with ChangeNotifier {
int _currentIndex = 0;
int get currentIndex => _currentIndex;
void changeIndex(int index) {
_currentIndex = index;
notifyListeners();
}
}
// En el widget
Consumer<NavigationProvider>(
builder: (context, provider, child) {
return BottomNavigationBar(
currentIndex: provider.currentIndex,
onTap: (index) => provider.changeIndex(index),
items: [...],
);
},
)
Mejores Prácticas
✅ Lo que SÍ debes hacer
- Usa entre 3 y 5 ítems máximo
- Mantén los labels cortos y descriptivos
- Usa iconos reconocibles
- Implementa estado persistente entre navegaciones
- Considera usar NavigationBar para nuevas apps
❌ Lo que NO debes hacer
- No uses más de 5 ítems
- Evita labels muy largos
- No mezcles diferentes patrones de navegación
- No olvides manejar el estado correctamente
- No uses NavigationBar sin Material 3
Tip Profesional
Para una experiencia de usuario óptima, considera usar PageStorage para mantener el estado de scroll y los datos de cada pestaña cuando el usuario navega entre ellas.
Ejercicios para Practicar
Ejercicio 1: App de Música
Crea una app de música con navegación entre Biblioteca, Buscar y Playlists.
Items sugeridos: Biblioteca, Buscar, Playlists, Configuración
Ejercicio 2: E-commerce App
Implementa una app de e-commerce con carrito que muestre badge con la cantidad.
Items sugeridos: Inicio, Categorías, Carrito (con badge), Perfil
Ejercicio 3: App de Noticias
Crea una app de noticias con navegación persistente usando Provider.
Items sugeridos: Noticias, Favoritos, Perfil, Configuración
Solución de Problemas Comunes
❌ Los íconos no cambian de color
Solución: Asegúrate de definir selectedItemColor y unselectedItemColor
selectedItemColor: Colors.blue, unselectedItemColor: Colors.grey
❌ El badge no se muestra correctamente
Solución: Usa el package badges y configura correctamente el Badge
Badge(badgeContent: Text('3'), child: Icon(Icons.notifications))
❌ La navegación no funciona
Solución: Verifica que currentIndex y onTap estén configurados
currentIndex: _selectedIndex, onTap: _onItemTapped