Tu App Android con diseño Material con AppBar y Scaffold en Jetpack Compose
Antonio Leiva

Desde hace muchos años, uno de los elementos más identificativos en las Apps Android ha sido la barra superior. Se la ha conocido con muchos nombres: ActionBar, Toolbar, AppBar…

Originalmente esa barra se incluía en las Apps por defecto, y lo único que podíamos hacer era mostrarla u ocultarla, pero poco más.

Con la llegada de Material Design, con sus animaciones, configuraciones de la Toolbar, etc., surgió la necesidad de que esa Toolbar fuera desacoplada y se pudiera incluir en cualquier parte.

¿Pero cómo usamos la Toolbar o AppBar ahora con Compose? En este artículo te voy a explicar esto y te hablaré de pasada sobre Scaffold, un layout que te va a ser de mucha ayuda para crear pantallas típicas de Material.

¡Atención! Si quieres acceder más rápido a todo el contenido en vídeo, organizado, con contenido extra, soporte y muchas más sorpresas, puedes apuntarte gratis a mi formación Compose Expert y ver gratis el primer módulo de más de 3 horas con todo lo necesario para empezar.

Configurando la Activity

Como hemos hablado anteriormente, el tema por defecto va a mostrar la barra en la parte superior si no lo decimos lo contrario.

Así que lo primero que le tenemos que decir a la Activity es que nos vamos a encargar nosotros de colocar la AppBar.

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.MyMovies.NoActionBar">
    ...
</activity>

Con el tema NoActionBar conseguimos ese objetivo. Si creaste un proyecto nuevo desde cero con soporte para Compose, la Activity que se creó ya tendrá este tema.

Usa Scaffold

Es cierto que, como en los XMLs, podemos tener AppBars independientes que podemos posicionar donde queramos.

Pero si queremos usarla en la posición habitual (en la parte superior de la pantalla), lo ideal es usar el Composable Scaffold.

Scaffold no es más que un layout con unos “huecos” predeterminados que nos permiten configurar aspectos típicos de una App en Android. Entre otros tenemos:

  • topBar: barra superior de navegación. Lo típico es usar una TopAppBar
  • bottomBar: barra inferior de navegación. Se puede usar por ejemplo una BottomAppBar o una BottomNavigation.
  • snackbarHost: sirve para poder mostrar Snackbars de forma sencilla
  • floatingActionButton: hay varias propiedades relacionadas con mostrar ese gran botón circular típico de Material
  • drawer: también tenemos varias propiedades para mostrar un menú lateral desplegable

Todos estos “huecos” realmente aceptan una lambda en la que podemos crear las vistas que necesitemos, no se nos obliga a nada. Pero hay muchos Composables específicos que nos simplificarán la tarea.

Hoy nos vamos a centrar en TopAppBar.

Pero antes vamos a configurar el Scaffold. Lo único que tenemos que hacer es incluir nuestro contenido previo dentro del mismo:

Scaffold {
    MediaList()
}

Hay una cosa que no se nos debe olvidar nunca. Si te fijas, en el IDE se ve que el Scaffold recibe un PaddingValues:

Ese padding lo calcula el layout en función de los componentes que hayamos añadido, y es importante aplicárselo al Composable raíz que añadamos al content.

Así que, tal y como vimos en el artículo de modifiers, vamos a añadir ese parámetro al MediaList, y aplicárselo al parent:

@Composable
fun MediaList(modifier: Modifier = Modifier) {
    LazyVerticalGrid(
        cells = GridCells.Adaptive(150.dp),
        contentPadding = PaddingValues(2.dp),
        modifier = modifier
    ) {
        ...
    }
}

Por último, se lo pasamos a MediaList aplicando el padding:

Scaffold { padding ->
    MediaList(Modifier.padding(padding))
}

Ahora ya estamos listos para pasar a la acción.

TopAppBar: la barra superior de nuestra App

Como casi todos los componentes en Compose, la TopAppBar nos da una configuración estándar muy sencilla con la que trabajar, pero luego podemos hacer muchas cosas para adaptarla a nuestras necesidades.

En su variante más sencilla solo tendríamos que hacer:

Scaffold(
    topBar = {
        TopAppBar(
            title = { Text(stringResource(R.string.app_name)) }
        )
    }
) { ... }

Si te fijas, tanto el argumento topBar como el title de la TopAppBar aceptan una lambda.

Esto ya lo hemos visto en otros ejemplos, y es lo que denominan “Slot API”. El API de Compose deja “huecos” en los que podemos añadir lo que queramos, en vez de asumir que en ese hueco irá un objeto de un tipo concreto.

Por ejemplo el title no te obliga a que sea de tipo Text. Puedes añadir la complejidad que quieras allí. Aquí un ejemplo sencillo, que añade un icono después del texto:

title = {
    Row {
        Text(stringResource(id = R.string.app_name))
        Spacer(Modifier.width(16.dp))
        Icon(Icons.Default.Android, contentDescription = null)
    }
}

TopAppBar: navigationIcon

Podemos definir de forma sencilla un icono de navegación que aparecerá en la parte izquierda. Se nos recomienda que se use un IconButton, que es un icono clickable:

navigationIcon = {
    IconButton(onClick = { /*TODO*/ }) {
        Icon(
            imageVector = Icons.Default.ArrowBack,
            contentDescription = null
        )
    }
}

TopAppBar: Actions

Seguro que vas a necesitar añadir acciones a la barra superior, así que aquí te voy a explicar cómo funcionan.

Al final la sección de acciones no es más que una Row. Así que podemos añadir los elementos que queramos, y estos se colocarán horizontalmente. Lo habitual será usar tambien IconButton:

actions = {
    IconButton(onClick = { /*TODO*/ }) {
        Icon(
            imageVector = Icons.Default.Search,
            contentDescription = null
        )
    }
    IconButton(onClick = { /*TODO*/ }) {
        Icon(
            imageVector = Icons.Default.Share,
            contentDescription = null
        )
    }
}

Si quisieras añadir un menú desplegable con más opciones, la cosa se complica un poco.

Dime en los comentarios si quieres ver otro artículo sobre el tema.

Con lo que ya tenemos, puedes revisar el código en el repositorio de GitHub.

Conclusión

Con esto finalizamos el repaso a Scaffold y a la TopApBar.

Si quieres seguir aprendiendo sobre Jetpack Compose, no te lo pienses y apúntate gratis a Compose Expert. Te llevarás más de 3 horas de contenido gratuito, con soporte y muchas más sorpresas.

Apúntate ahora a Compose Expert y accede a más de 3h de contenido gratuito, soporte, extras y mucho más totalmente gratis.

Si te fijas, el código se nos está yendo un poco de las manos, y como cualquier otra parte de nuestra App, necesita ser estructurado correctamente. En el siguiente vídeo te voy a dar 5 consejos para organizarlo.

Quizá también te interese…

Navegación en Jetpack Compose con Navigation Compose

Navegación en Jetpack Compose con Navigation Compose

Jetpack Compose es un cambio de paradigma enorme en muchos aspectos. Cambia la forma de pensar en casi todos los puntos involucrados en el desarrollo de una App Android. Y la navegación no iba a ser menos. ¿Cómo se navega en Jetpack Compose? ¿Qué opciones tenemos?...

5 consejos para estructurar el código en Jetpack Compose

5 consejos para estructurar el código en Jetpack Compose

Escribir la interfaz con código es genial, pero puede ser que pronto se nos vaya de las manos. Aunque la forma de escribir el código de Jetpack Compose es muy natural y relativamente directa, sí que es verdad que en pro de la flexibilidad, también hay algunos...

0 comentarios

Enviar un comentario

Los datos personales que proporciones a través de este formulario quedarán registrados en un fichero de Antonio Leiva Gordillo, con el fin de gestionar los comentarios que realizas en este blog. La legitimación se realiza a través del consentimiento de la parte interesada. Si no se acepta, no podrás comentar en este blog. Los datos que proporciona solo se utilizan para evitar el correo no deseado y no se usarán para nada más. Puede ejercer los derechos de acceso, rectificación, cancelación y oposición en contacto@devexperto.com.

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Acepto la política de privacidad *