TabBar en Flutter
Implementa pestañas elegantes y funcionales en tus apps
Descargar Ejemplos Completos¿Qué es TabBar?
El TabBar es un widget fundamental en Flutter que permite organizar contenido en pestañas horizontales, ideal para mostrar diferentes secciones de una aplicación de manera organizada.
Tipos de TabBars
DefaultTabBar
TabBar estándar con indicador simple
TabBar Personalizado
Con colores, formas y estilos personalizados
Scrollable TabBar
Para muchas pestañas con desplazamiento horizontal
Implementación Básica
DefaultTabController con TabBar
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: 'TabBar Example',
theme: ThemeData(primarySwatch: Colors.blue),
home: const TabBarExample(),
);
}
}
class TabBarExample extends StatelessWidget {
const TabBarExample({super.key});
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('Mi App con Pestañas'),
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.home), text: 'Inicio'),
Tab(icon: Icon(Icons.search), text: 'Buscar'),
Tab(icon: Icon(Icons.person), text: 'Perfil'),
],
),
),
body: const TabBarView(
children: [
Center(child: Text('Contenido de Inicio')),
Center(child: Text('Contenido de Búsqueda')),
Center(child: Text('Contenido de Perfil')),
],
),
),
);
}
}
Propiedades Principales
tabs
Lista de widgets Tab que se mostrarán
Tipo: List<Widget>
Requerido: Sí
controller
Controla la pestaña seleccionada y la animación
Tipo: TabController
Requerido: No (se crea automático)
isScrollable
Permite desplazamiento horizontal
Tipo: bool
Por defecto: false
indicatorColor
Color del indicador de pestaña activa
Tipo: Color
Por defecto: Theme accentColor
labelColor
Color del texto de pestaña activa
Tipo: Color
Por defecto: Theme accentColor
unselectedLabelColor
Color del texto de pestañas inactivas
Tipo: Color
Por defecto: Theme unselectedWidgetColor
Widget Tab
text
Texto de la pestaña
text: 'Inicio'
icon
Icono de la pestaña
icon: Icon(Icons.home)
child
Widget personalizado para la pestaña
child: Text('Inicio')
height
Altura personalizada de la pestaña
height: 60
Ejemplos de Tabs:
// Tab con icono y texto
Tab(icon: Icon(Icons.home), text: 'Inicio')
// Tab solo con texto
Tab(text: 'Configuración')
// Tab solo con icono
Tab(icon: Icon(Icons.star))
// Tab personalizado
Tab(
child: Row(
children: [
Icon(Icons.notifications),
SizedBox(width: 4),
Text('Notificaciones'),
],
),
)
Ejemplos Visuales
1. TabBar Clásica
Lista de Chats
- Ana - Hola!
- Carlos - ¿Cómo estás?
- Maria - Reunión mañana
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('Mi App'),
bottom: TabBar(
tabs: [
Tab(text: 'Chats'),
Tab(text: 'Estados'),
Tab(text: 'Llamadas'),
],
),
),
body: TabBarView(
children: [
ChatsScreen(),
StatusScreen(),
CallsScreen(),
],
),
),
)
2. TabBar con Iconos
Tu Biblioteca Musical
Reproduciendo: Canción Actual
TabBar(
tabs: [
Tab(icon: Icon(Icons.music_note), text: 'Música'),
Tab(icon: Icon(Icons.podcasts), text: 'Podcasts'),
Tab(icon: Icon(Icons.radio), text: 'Radio'),
],
)
3. TabBar Personalizada
Estadísticas de Hoy
Ventas: \$1,250
Visitas: 342
TabBar(
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(25),
color: Colors.deepPurple,
),
labelColor: Colors.white,
unselectedLabelColor: Colors.deepPurple,
tabs: [
Tab(text: 'Hoy'),
Tab(text: 'Semana'),
Tab(text: 'Mes'),
Tab(text: 'Año'),
],
)
TabController Manual
Para un control más avanzado, puedes usar TabController manualmente con StatefulWidget.
TabController con StatefulWidget
class TabControllerExample extends StatefulWidget {
const TabControllerExample({super.key});
@override
State<TabControllerExample> createState() => _TabControllerExampleState();
}
class _TabControllerExampleState extends State<TabControllerExample>
with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TabController Manual'),
bottom: TabBar(
controller: _tabController,
tabs: const [
Tab(text: 'Noticias'),
Tab(text: 'Deportes'),
Tab(text: 'Tecnología'),
],
),
),
body: TabBarView(
controller: _tabController,
children: const [
NewsScreen(),
SportsScreen(),
TechnologyScreen(),
],
),
);
}
}
Personalizador de TabBar
Este es el contenido de la pestaña seleccionada...
// El código se generará aquí
TabBarView
El widget TabBarView muestra el contenido correspondiente a cada pestaña.
Implementación de TabBarView
TabBarView(
children: [
// Contenido para la primera pestaña
ListView.builder(
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
title: Text('Elemento \$index'),
);
},
),
// Contenido para la segunda pestaña
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 10,
itemBuilder: (context, index) {
return Card(
child: Center(child: Text('Card \$index')),
);
},
),
// Contenido para la tercera pestaña
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.person, size: 64),
Text('Perfil de Usuario'),
],
),
),
],
)
Mejores Prácticas
✅ Lo que SÍ debes hacer
- Usa entre 2 y 5 pestañas máximo
- Mantén los labels cortos y descriptivos
- Usa iconos reconocibles cuando sea posible
- Considera usar TabController manual para casos complejos
- Usa TabBarView para contenido relacionado
❌ Lo que NO debes hacer
- No uses más de 5-6 pestañas (mejor usar scrollable)
- Evita labels muy largos
- No mezcles diferentes patrones de navegación
- No olvides dispose() del TabController manual
- No uses pestañas para funcionalidades no relacionadas
Tip Profesional
Para mejorar el rendimiento con muchas pestañas, considera usar AutomaticKeepAliveClientMixin para mantener el estado de cada pestaña y evitar reconstrucciones innecesarias.
Ejercicios para Practicar
Ejercicio 1: App de Noticias
Crea una app de noticias con pestañas para diferentes categorías.
Pestañas sugeridas: Últimas, Deportes, Tecnología, Entretenimiento
Ejercicio 2: App del Clima
Implementa una app del clima con pestañas para diferentes ciudades.
Pestañas sugeridas: Ciudad Actual, Favoritas, Pronóstico Extendido
Ejercicio 3: App de Tareas
Crea una app de tareas con pestañas para diferentes estados.
Pestañas sugeridas: Todas, Pendientes, Completadas, Archivadas
Solución de Problemas Comunes
❌ Las pestañas no cambian al deslizar
Solución: Asegúrate de usar el mismo TabController en TabBar y TabBarView
controller: _tabController // en ambos widgets
❌ Error: 'TabController vsync was null'
Solución: Implementa SingleTickerProviderStateMixin en tu State
with SingleTickerProviderStateMixin
❌ El contenido no se actualiza
Solución: Usa AutomaticKeepAliveClientMixin para mantener el estado
with AutomaticKeepAliveClientMixin
Recursos Adicionales
📚 Documentación Oficial
Consulta la documentación completa de TabBar en flutter.dev
Ver Documentación