Navegación inferior y pestañas
Implemente la navegación entre varias secciones con BottomNavigationView conectado a NavController y pestañas deslizables con TabLayout, ViewPager2 y TabLayoutMediator.
Navegación inferior y pestañas es una lección gratuita de Android Academy en CoddyKit. Esta es la lección 5 de 5. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Android Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Android Academy incluye 5 lecciones en total.
Patrones de navegación
Dos patrones habituales para la navegación de nivel superior en aplicaciones Android:
- Navegación inferior — para entre 3 y 5 destinos principales. Siempre visible. Ideal para secciones con la misma importancia (por ejemplo, Inicio, Buscar y Perfil).
- Pestañas — para contenido relacionado dentro de una pantalla (por ejemplo, Todas / Activas / Completadas). A menudo se utilizan con ViewPager2 para admitir el deslizamiento.
Diseño de BottomNavigationView
Añada BottomNavigationView y un FragmentContainerView al diseño de su Activity:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu" />
</LinearLayout>Elementos del menú de navegación inferior
Defina los elementos en res/menu/bottom_nav_menu.xml. El ID de cada elemento debe coincidir con el ID de destino del grafo de navegación:
<!-- res/menu/bottom_nav_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/homeFragment"
android:icon="@drawable/ic_home"
android:title="Home" />
<item
android:id="@+id/searchFragment"
android:icon="@drawable/ic_search"
android:title="Search" />
<item
android:id="@+id/profileFragment"
android:icon="@drawable/ic_person"
android:title="Profile" />
</menu>Conexión con NavController
Conecte BottomNavigationView al NavController en onCreate():
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHost = supportFragmentManager
.findFragmentById(R.id.navHostFragment) as NavHostFragment
val navController = navHost.navController
binding.bottomNav.setupWithNavController(navController)
// Hide bottom nav on detail screens:
navController.addOnDestinationChangedListener { _, destination, _ ->
binding.bottomNav.visibility = when (destination.id) {
R.id.detailFragment -> View.GONE
else -> View.VISIBLE
}
}
}
}Insignias en la navegación inferior
Muestre insignias de notificación en los elementos de la navegación inferior:
// Show a numbered badge:
val badge = binding.bottomNav.getOrCreateBadge(R.id.homeFragment)
badge.number = 5
badge.isVisible = true
// Show dot badge (no number):
val dotBadge = binding.bottomNav.getOrCreateBadge(R.id.searchFragment)
dotBadge.isVisible = true
// Remove badge:
binding.bottomNav.removeBadge(R.id.homeFragment)TabLayout
TabLayout muestra pestañas horizontales, normalmente utilizadas con ViewPager2 para contenido que se puede recorrer mediante deslizamiento:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>ViewPager2 + FragmentStateAdapter
Cree un adaptador que proporcione un fragmento para cada posición de pestaña:
class TasksPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
override fun getItemCount() = 3
override fun createFragment(position: Int): Fragment = when (position) {
0 -> AllTasksFragment()
1 -> ActiveTasksFragment()
2 -> CompletedTasksFragment()
else -> throw IllegalStateException("Unknown tab $position")
}
}TabLayoutMediator
Conecte ViewPager2 y TabLayout mediante TabLayoutMediator:
// In Fragment.onViewCreated():
val adapter = TasksPagerAdapter(this)
binding.viewPager.adapter = adapter
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = when (position) {
0 -> "All"
1 -> "Active"
2 -> "Done"
else -> ""
}
}.attach()
// Disable swipe if needed:
binding.viewPager.isUserInputEnabled = falsePestañas con iconos
Añada iconos a las pestañas de TabLayout:
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
when (position) {
0 -> {
tab.text = "Home"
tab.setIcon(R.drawable.ic_home)
}
1 -> {
tab.text = "Search"
tab.setIcon(R.drawable.ic_search)
}
2 -> {
tab.text = "Profile"
tab.setIcon(R.drawable.ic_person)
}
}
}.attach()Límite de páginas fuera de pantalla
De forma predeterminada, ViewPager2 solo mantiene en memoria la página adyacente. Aumente offscreenPageLimit si sus pestañas deben mantenerse activas al cambiar de una a otra:
// Keep 2 pages on each side alive:
binding.viewPager.offscreenPageLimit = 2
// Note: FragmentStateAdapter saves and restores state for off-screen
// fragments even when offscreenPageLimit is 1 (default).
// Only increase this when you need views (not just state) to survive.Navegación inferior frente a pestañas: cómo elegir
Guía rápida para elegir el patrón adecuado:
- Use la navegación inferior cuando haya entre 3 y 5 destinos de nivel superior con funciones diferentes (Inicio, Buscar, Notificaciones y Perfil).
- Use pestañas cuando filtre o categorice el mismo tipo de contenido (tareas Todas / Activas / Archivadas).
- Combine ambas: navegación inferior para las secciones de nivel superior y pestañas dentro de una sección para aplicar subfiltros.
Comprobación rápida
¿Qué clase conecta un TabLayout con un ViewPager2 y establece las etiquetas de las pestañas?
Repaso: navegación inferior y pestañas
Navegación entre varias secciones, bien implementada:
- BottomNavigationView — entre 3 y 5 destinos con la misma importancia; los ID del menú coinciden con los ID de destino del grafo de navegación
setupWithNavController()— cambio automático de pestañas y pila de retroceso- Insignias con
getOrCreateBadge() - TabLayout + ViewPager2 — vistas del mismo contenido que se pueden recorrer mediante deslizamiento y filtrar
TabLayoutMediator— conecta ambos componentes y establece las etiquetas
A continuación: pruebas unitarias con JUnit para mantener la fiabilidad de su código.
Preguntas frecuentes
¿La lección «Navegación inferior y pestañas» es gratis?
Sí — el texto completo de «Navegación inferior y pestañas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Android Academy, actualiza a CoddyKit PRO. El curso de Android Academy incluye 5 lecciones en total.
¿Qué aprenderé en «Navegación inferior y pestañas»?
Implemente la navegación entre varias secciones con BottomNavigationView conectado a NavController y pestañas deslizables con TabLayout, ViewPager2 y TabLayoutMediator. Practicas Android Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Android Academy?
No se requiere experiencia previa. Android Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 5 de 5.
¿Cuánto tiempo toma la lección «Navegación inferior y pestañas»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Android Academy?
Sí. Cada lección de Android Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Fundamentos de Material Design
- Temas y estilos
- Vistas personalizadas
- Animaciones y transiciones
- Navegación inferior y pestañas