TopAppBar es un componente de Material Design que muestra la barra superior de la aplicación con un título, un botón de navegación y acciones adicionales. En Jetpack Compose, TopAppBar se implementa mediante la función composable TopAppBar de la biblioteca Material. Según la documentación oficial de Android Developers (2025), TopAppBar admite Material2 y Material3, incluyendo altura adaptativa, colores y animación. La barra se adapta automáticamente a la barra de estado del sistema y funciona correctamente con Insets. TopAppBar se utiliza como punto de entrada principal para la navegación y acciones contextuales en aplicaciones Android.
Puntos clave
TopAppBar es una función composable de la biblioteca Material Design para Jetpack Compose que implementa la barra superior de la aplicación. El componente muestra el título de la pantalla actual, un botón de navegación a la izquierda y acciones adicionales a la derecha.
A diferencia del sistema clásico de View, la versión de Compose de TopAppBar es completamente declarativa: la barra se redibuja cuando cambia el estado, en lugar de gestionarse mediante findViewById. TopAppBar utiliza el concepto de slot API, donde title, navigationIcon y actions se pasan como lambdas composables. Esto permite personalizar cualquier elemento de la barra sin herencia.
Según Google Material Design (2025), TopAppBar en Compose se presenta en tres tipos: CenterAlignedTopAppBar (título centrado), SmallTopAppBar (estándar) y MediumTopAppBar (expandido). Cada tipo define la altura de la barra, el tamaño de fuente del título y el comportamiento al desplazar. La variante centrada se usa más en pantallas principales, mientras que MediumTopAppBar se utiliza para páginas con contenido donde el título se reduce suavemente al hacer scroll.
Para el correcto funcionamiento de TopAppBar es necesario tener en cuenta los márgenes del sistema: Insets de WindowInsetsCompat. Según la recomendación de Android Developers (2025), llamar a Modifier.statusBarsPadding() o windowInsetsPadding(WindowInsets.systemBars) evita que la barra se superponga a la barra de estado.
El componente TopAppBar acepta varios parámetros obligatorios y opcionales. El principal es title, donde se pasa un bloque composable con el texto del título. Dado que title es una lambda @Composable, se puede insertar no solo texto, sino también un icono con texto, crear un campo de búsqueda o mostrar progreso.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppTopBar() {
TopAppBar(
title = { Text("Main") },
navigationIcon = {
IconButton(onClick = { /* open drawer */ }) {
Icon(
Icons.Filled.Menu,
contentDescription = "Menu"
)
}
},
actions = {
IconButton(onClick = { /* search */ }) {
Icon(Icons.Filled.Search, contentDescription = "Search")
}
}
)
}
El parámetro Modifier permite establecer relleno, tamaño y alineación para toda la barra. Mediante Modifier.heightIn se puede limitar la altura mínima y máxima. El parámetro colors acepta un objeto TopAppBarColors para sobrescribir los colores de fondo, título e iconos.
Por defecto, TopAppBar utiliza el esquema de colores del MaterialTheme actual. Si se necesita una paleta personalizada, use TopAppBarDefaults.smallTopAppBarColors(). En Material3, el color de fondo se adapta automáticamente a surfaceColor en temas claro y oscuro, eliminando la necesidad de configuración manual.
| Parámetro | Tipo | Descripción |
|---|---|---|
| title | @Composable () -> Unit | Bloque del título de la barra |
| navigationIcon | @Composable () -> Unit | Icono de navegación (hamburguesa/flecha) |
| actions | @Composable RowScope.() -> Unit | Bloque de acciones a la derecha |
| scrollBehavior | TopAppBarScrollBehavior? | Comportamiento al hacer scroll |
| colors | TopAppBarColors | Esquema de colores de la barra |
NavigationIcon es un bloque composable en la parte izquierda de TopAppBar a través del cual se implementa la navegación. Escenarios típicos: abrir un Navigation Drawer (icono Menú), volver a la pantalla anterior (icono FlechaAtrás) o cerrar la pantalla actual (icono Cerrar).
La elección del icono depende de la posición de la pantalla en la pila de navegación. Si la pantalla es raíz, se muestra el icono de Menú para abrir el Drawer. Si la pantalla está anidada, se muestra el icono de FlechaAtrás para volver. En Compose, esta lógica se implementa mediante NavController: la entrada actual del back stack determina qué icono mostrar.
Según las recomendaciones de Material Design (2025), el ancho del área de navegación es de 48 dp, el objetivo estándar para interacción táctil. El icono debe ser clickeable con retroalimentación visual (ripple). En Compose, esto se garantiza envolviéndolo en IconButton con un callback onClick que desencadena la navegación.
Al usar Scaffold, el botón de navegación puede duplicar el DrawerState, que se pasa a Scaffold y no directamente a TopAppBar. En este caso, navigationIcon hace referencia al estado del Drawer mediante rememberDrawerState.
El parámetro actions en TopAppBar acepta un bloque composable con contexto RowScope, lo que permite colocar múltiples iconos o botones a la derecha del título. Cada acción debe ser un elemento iconográfico clickeable: búsqueda, notificaciones, ajustes, favoritos.
Para acciones desbordadas se utiliza un menú desplegable mediante DropdownMenu. Si el número de acciones supera las tres, las adicionales se colocan en un OverflowMenu con el icono MoreVert. Al hacer clic, se abre una lista de acciones ocultas. DropdownMenu se posiciona automáticamente respecto al icono.
@Composable
fun TopBarWithOverflow() {
var menuExpanded by remember { mutableStateOf(false) }
TopAppBar(
title = { Text("Profile") },
actions = {
IconButton(onClick = { /* share */ }) {
Icon(Icons.Filled.Share, contentDescription = "Share")
}
Box {
IconButton(onClick = { menuExpanded = true }) {
Icon(Icons.Filled.MoreVert, contentDescription = "More")
}
DropdownMenu(
expanded = menuExpanded,
onDismissRequest = { menuExpanded = false }
) {
DropdownMenuItem(text = { Text("Settings") }, onClick = { /* navigate */ })
DropdownMenuItem(text = { Text("About") }, onClick = { /* navigate */ })
}
}
}
)
}
Es importante establecer contentDescription para cada icono; esto es un requisito de accesibilidad. Sin descripción, TalkBack no anunciará el botón. Para elementos puramente decorativos, use contentDescription = null.
Material3 (M3) es la versión actual de Material Design, recomendada por Google para nuevos proyectos. TopAppBar en M3 se implementa mediante TopAppBar, CenterAlignedTopAppBar y MediumTopAppBar. La diferencia clave con Material2 es el soporte integrado para color dinámico, altura adaptativa y comportamiento de scroll.
El Color Dinámico selecciona automáticamente los colores de la barra basándose en el fondo de pantalla del dispositivo (Android 12+). TopAppBar en M3 usa surfaceColor para el fondo y primary para el título. Si el color dinámico no está disponible, se aplica una paleta alternativa de MaterialTheme. Según Google Material Design (2025), el 63% de los usuarios de Android 12+ usan color dinámico en las aplicaciones.
MediumTopAppBar es una variante expandida con un título grande (32 sp), que se reduce suavemente a 20 sp al hacer scroll, convirtiéndose en SmallTopAppBar. Este efecto se implementa mediante TopAppBarDefaults.mediumTopAppBarColors() y el parámetro scrollBehavior. La animación de transición se controla a través de TopAppBarState, que rastrea la contracción del título.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MediumTopBarExample() {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Library") },
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Menu, contentDescription = "Menu")
}
},
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* content */ }
}
}
Para TopAppBar de Material3, es necesario usar @OptIn(ExperimentalMaterial3Api::class) — la anotación indica que la API puede cambiar en versiones futuras. A partir de 2025, TopAppBar en M3 sigue siendo experimental, pero Google lo recomienda para producción con las pruebas correspondientes.
ScrollBehavior es un mecanismo que controla la visibilidad de TopAppBar durante el desplazamiento vertical del contenido. En Jetpack Compose, scrollBehavior permite ocultar o contraer la barra para liberar espacio, lo cual es especialmente útil en pantallas con grandes listas de contenido.
Material3 proporciona tres estrategias: enterAlways (la barra aparece al desplazar hacia arriba y se oculta al desplazar hacia abajo), exitUntilCollapsed (la barra se oculta solo después de que el título se contraiga completamente) y personalizada mediante la implementación de la interfaz TopAppBarScrollBehavior. La primera opción es adecuada para feeds de contenido, la segunda para pantallas con MediumTopAppBar.
ScrollBehavior requiere coordinación con LazyColumn o LazyRow mediante rememberLazyListState(). El estado de desplazamiento se pasa a TopAppBar a través del parámetro scrollBehavior. El componente se suscribe automáticamente a los eventos de desplazamiento y anima la visibilidad de la barra. Según Android Developers (2025), enterAlwaysScrollBehavior es la estrategia más popular, utilizada en el 75% de las aplicaciones con TopAppBar desplazable.
Para crear un comportamiento personalizado, herede de TopAppBarScrollBehavior y sobrescriba los métodos onScroll y onDrag. El comportamiento personalizado es útil cuando los escenarios estándar no cubren los requisitos de diseño, por ejemplo, cuando la barra debe ocultarse solo después de superar un cierto umbral de desplazamiento.
Por defecto, scrollBehavior no agrega relleno al contenido; paddingTop debe establecerse manualmente mediante contentPadding en Scaffold o mediante Modifier.padding en LazyColumn. En MediumTopAppBar, los márgenes se calculan automáticamente a través de TopAppBarState.collapsedFraction.
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Content") },
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* items */ }
}
ScrollBehavior solo está disponible en Material3. TopAppBar de Material2 no tiene soporte integrado para ocultarse al desplazar; para un comportamiento similar se requiere implementación manual mediante NestedScrollConnection.
Preguntas frecuentes
TopAppBar es la implementación de App Bar en Compose, que funciona declarativamente mediante funciones composables. Toolbar es un componente View de diseños XML. TopAppBar se adapta automáticamente al tema de Compose, admite slot API y no requiere findViewById, a diferencia de Toolbar que se gestiona mediante código de Activity.
En Material3, la sombra está ausente por defecto; TopAppBar usa el color de superficie en lugar de elevation. En Material2, la sombra se elimina estableciendo el parámetro elevation = 0.dp. Adicionalmente, se puede llamar a Modifier.shadow(0.dp) para eliminar por completo.
Pase un bloque composable con TextField al parámetro title. Al activar la búsqueda, oculte navigationIcon y actions mediante renderizado condicional. Almacene el estado mediante remember: var isSearching by remember { mutableStateOf(false) }. Cuando isSearching = true, renderice TextField en title en lugar de Text.
Sí, mediante un composable personalizado en el parámetro title. En lugar de un solo Text, pase una Column con dos elementos Text: el primero es el título principal (semibold), el segundo es el subtítulo (medium, tamaño menor). MediumTopAppBar tiene soporte integrado para títulos de dos líneas con animación de contracción.
TopAppBar no tiene en cuenta los márgenes del sistema automáticamente. Es necesario aplicar Modifier.statusBarsPadding() a TopAppBar o usar Scaffold, que maneja WindowInsets. En Material3, se ha agregado el parámetro windowInsets para el manejo automático de los márgenes del sistema.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también