1. Antes de comenzar
En el codelab anterior, creaste una app de Affirmations que muestra una lista de texto en una RecyclerView
.
En este codelab de seguimiento, agregarás una imagen inspiradora a cada afirmación de tu app. Debes mostrar el texto y la imagen de cada afirmación dentro de una tarjeta con el widget MaterialCardView
de la biblioteca de componentes de Material Design para Android. Luego, para terminar la app, perfeccionarás la IU a fin de crear una experiencia del usuario más coherente y atractiva. Esta es una captura de pantalla de la app completada:
Requisitos previos
- Poder agregar recursos de imagen a una app.
- Estar familiarizado con la modificación de un diseño XML.
- Ser capaz de crear una app que muestre una lista de texto en un elemento
RecyclerView
- Ser capaz de crear un adaptador para un elemento
RecyclerView
Qué aprenderás
- Cómo agregar imágenes a la lista de afirmaciones que se muestran en un elemento
RecyclerView
. - Cómo usar el objeto
MaterialCardView
en el diseño de un elementoRecyclerView
. - Cómo realizar cambios visuales en la IU para que la app luzca mejor.
Qué compilarás
- Una app Affirmations mejorada que usa un elemento
RecyclerView
para mostrar una lista de tarjetas. Cada tarjeta contiene una imagen y un texto de afirmación.
Requisitos
- Una computadora que tenga instalado Android Studio 4.1 o una versión posterior
- Acceso a una conexión a Internet para descargar archivos de imagen
- La app Affirmations del codelab anterior titulado Cómo crear una app Affirmations. (No se brinda código de partida. Crear la app es un requisito previo).
2. Agrega imágenes a los elementos de la lista
Hasta ahora, creaste un adaptador ItemAdapter
para mostrar strings de afirmación en una RecyclerView
. En términos funcionales, es óptimo; pero, en términos visuales, no es muy atractivo. En esta tarea, modificarás el diseño del elemento de la lista y el código del adaptador para mostrar imágenes con las afirmaciones.
Cómo descargar las imágenes
- Para comenzar, abre el proyecto de la app Affirmations en Android Studio desde el codelab anterior. Si no tienes este proyecto, repasa los pasos del codelab anterior para crear ese proyecto. Luego, regresa a este codelab.
- A continuación, descarga los archivos de imagen en tu computadora. Debería haber diez imágenes, una para cada afirmación de tu app. Los nombres de los archivos deben abarcar de
image1.jpg
aimage10.jpg
. - Copia las imágenes de tu computadora en la carpeta res > drawable de tu proyecto (
app/src/main/res/drawable
) en Android Studio. Una vez que se agreguen estos recursos a tu app, podrás acceder a estas imágenes desde tu código con tus ID de recurso, comoR.drawable.image1
. (Es posible que debas volver a compilar tu código para que Android Studio encuentre la imagen).
Ya puedes usar las imágenes en la app.
Cómo agregar compatibilidad con imágenes en la clase Affirmation
En este paso, agregarás una propiedad en la clase de datos Affirmation
a fin de conservar un valor para un ID de recurso de imagen. De esa manera, una sola instancia de objeto Affirmation
contendrá un ID de recurso para el texto de la afirmación y un ID de recurso para la imagen de la afirmación.
- Abre el archivo
Affirmation.kt
dentro del paquetemodel
. - Para modificar el constructor de la clase
Affirmation
, agrega otro parámetroInt
llamadoimageResourceId
.
Cómo usar anotaciones de recursos
Los dos elementos stringResourceId
y imageResourceId
son valores enteros. Si bien parece que está bien, el llamador podría pasar accidentalmente los argumentos en el orden incorrecto (primero imageResourceId
en lugar de stringResourceId
).
Para evitar esto, puedes usar las anotaciones de recursos. Las anotaciones son útiles porque agregan información adicional a las clases, los métodos o los parámetros. Las anotaciones siempre se declaran con un símbolo @. En este caso, agrega la anotación @StringRes
a tu propiedad de ID del recurso de strings y la anotación @DrawableRes
a tu propiedad de ID del recurso de elementos de diseño. Recibirás una advertencia si proporcionas el tipo de ID de recurso incorrecto.
- Agrega la anotación
@StringRes
astringResourceId
. - Agrega la anotación
@DrawableRes
aimageResourceId
. - Asegúrate de que las importaciones
androidx.annotation.DrawableRes
yandroidx.annotation.StringRes
se agreguen en la parte superior de tu archivo después de la declaración del paquete.
Affirmation.kt
package com.example.affirmations.model
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
data class Affirmation(
@StringRes val stringResourceId: Int,
@DrawableRes val imageResourceId: Int
)
Cómo inicializar la lista de afirmaciones con imágenes
Ahora que cambiaste el constructor de la clase Affirmation
, debes actualizar la clase Datasource
. Pasa un ID de recurso de imagen a cada objeto Affirmation
que se inicialice.
- Abre
Datasource.kt
. Deberías ver un error para cada instancia deAffirmation
. - Para cada elemento
Affirmation
, agrega el ID de recurso de una imagen como argumento, por ejemplo,R.drawable.image1
.
Datasource.kt
package com.example.affirmations.data
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
class Datasource() {
fun loadAffirmations(): List<Affirmation> {
return listOf<Affirmation>(
Affirmation(R.string.affirmation1, R.drawable.image1),
Affirmation(R.string.affirmation2, R.drawable.image2),
Affirmation(R.string.affirmation3, R.drawable.image3),
Affirmation(R.string.affirmation4, R.drawable.image4),
Affirmation(R.string.affirmation5, R.drawable.image5),
Affirmation(R.string.affirmation6, R.drawable.image6),
Affirmation(R.string.affirmation7, R.drawable.image7),
Affirmation(R.string.affirmation8, R.drawable.image8),
Affirmation(R.string.affirmation9, R.drawable.image9),
Affirmation(R.string.affirmation10, R.drawable.image10)
)
}
}
Cómo agregar ImageView al diseño del elemento de la lista
Para mostrar una imagen por cada afirmación de tu lista, debes agregar un elemento ImageView
al diseño del elemento. Como ahora tienes dos vistas (TextView
y ImageView
), debes ubicarlas como vistas secundarias dentro de un elemento ViewGroup
. Para organizar las vistas en una columna vertical, puedes usar un elemento LinearLayout
. LinearLayout
alinea todas las vistas secundarias en una sola dirección, de manera vertical u horizontal.
- Abre res > layout > list_item.xml. Agrega un elemento
LinearLayout
alrededor del objetoTextView
existente y configura la propiedadorientation
envertical
. - Mueve la línea de declaración
xmlns schema
del elementoTextView
al elementoLinearLayout
para corregir el error.
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
- Dentro del elemento
LinearLayout,
antes deTextView,
, agrega un objetoImageView
con un ID de recurso deitem_image
. - Configura el ancho de
ImageView
enmatch_parent
y la altura en194dp
. Según el tamaño de la pantalla, este valor debería mostrar algunas tarjetas en la pantalla en cualquier momento. - Configura el elemento
scaleType
encenterCrop.
- Configura el atributo
importantForAccessibility
enno
, ya que la imagen se usa con fines decorativos.
<ImageView
android:layout_width="match_parent"
android:layout_height="194dp"
android:id="@+id/item_image"
android:importantForAccessibility="no"
android:scaleType="centerCrop" />
Cómo actualizar ItemAdapter para configurar la imagen
- Abre
adapter/ItemAdapter.kt
(app > java > adapter > ItemAdapter). - Ve a la clase
ItemViewHolder
. - Una instancia
ItemViewHolder
debe contener una referencia aTextView
y una referencia aImageView
en el diseño del elemento de la lista. Realiza el siguiente cambio.
Debajo de la inicialización de la propiedad textView
, agrega un elemento val
llamado imageView
. Usa findViewById()
para buscar la referencia al objeto ImageView
con el elemento item_image
de ID y asígnalo a la propiedad imageView
.
ItemAdapter.kt
class ItemViewHolder(private val view: View): RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
val imageView: ImageView = view.findViewById(R.id.item_image)
}
- Busca la función
onBindViewHolder()
enItemAdapter
. - Anteriormente, configuraste el elemento
stringResourceId
de la afirmación entextView
, en el objetoItemViewHolder
. Ahora, configura el objetoimageResourceId
del elemento de la afirmación en el parámetroImageView
de la vista de elementos de la lista.
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
holder.imageView.setImageResource(item.imageResourceId)
}
- Ejecuta la app y desplázate por la lista de afirmaciones.
¡La app parece mucho más atractiva con las imágenes! Sin embargo, todavía puedes mejorar la IU de la app. En la siguiente sección, realizarás ajustes pequeños en la app para mejorar la IU.
3. Perfecciona la IU
Hasta ahora, compilaste una app funcional que consiste en una lista de imágenes y strings de afirmaciones. En esta sección, verás cómo los cambios pequeños en el código y XML pueden lograr que la app luzca mejor.
Cómo agregar padding
Para comenzar, agrega algunos espacios en blanco entre los elementos de la lista.
- Abre
item_list.xml
(app > res > layout > item_list.xml) y agrega padding16dp
al elementoLinearLayout
existente.
list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
- Agrega padding
16dp
en el objetoitem_title
TextView
. - En el elemento
TextView
, configura el atributotextAppearance
en?attr/textAppearanceHeadline6
.textAppearance
es un atributo que te permite definir un estilo específico de texto. Para ver otros posibles valores de apariencia de texto predefinidos, consulta la sección TextAppearances en esta entrada de blog sobre atributos comunes del tema.
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:textAppearance="?attr/textAppearanceHeadline6" />
- Ejecuta la app. ¿Crees que la lista luce mejor?
Cómo usar tarjetas
Es difícil determinar si una imagen pertenece al texto de la afirmación superior o inferior. Para corregir este problema, puedes usar una vista de tarjetas. La vista de tarjetas brinda una manera sencilla de incluir un grupo de vistas y, a la vez, proporciona un estilo coherente para el contenedor. Para obtener más orientación sobre el uso de tarjetas con Material Design, consulta esta guía sobre tarjetas.
- Agrega un elemento
MaterialCardView
alrededor del objetoLinearLayout
existente. - Una vez más, mueve la declaración del esquema de
LinearLayout
aMaterialCardView
. - Configura el elemento
layout_width
deMaterialCardView
enmatch_parent
y el objetolayout_height
enwrap_content
. - Agrega un elemento
layout_margin
de8dp
. - Quita el padding del objeto
LinearLayout
para que no tengas mucho espacio en blanco. - Ahora, vuelve a ejecutar la app. ¿Puedes diferenciar mejor cada afirmación con
MaterialCardView
?
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/item_image"
android:layout_width="match_parent"
android:layout_height="194dp"
android:importantForAccessibility="no"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:textAppearance="?attr/textAppearanceHeadline6" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Cómo cambiar los colores del tema de la app
Es posible que el color predeterminado del tema de la app no sea tan tranquilo como otras opciones que podrías elegir. En esta tarea, cambiarás el color del tema de la app a azul. Puedes volver a cambiarlo según tus propias ideas.
En este vínculo, puedes encontrar tonos predefinidos de azul de la paleta de colores de Material Design.
En este codelab, usarás los siguientes colores de la paleta de Material Design:
- blue_200:
#FF90CAF9
- blue_500:
#FF2196F3
- blue_700:
#FF1976D2
Cómo agregar recursos de color
Define los colores que se usan en tu app en un lugar centralizado: el archivo colors.xml
.
- Abre
colors.xml
(res > values > colors.xml). - Agrega nuevos recursos de color al archivo para los colores azules que se definen a continuación:
<color name="blue_200">#FF90CAF9</color>
<color name="blue_500">#FF2196F3</color>
<color name="blue_700">#FF1976D2</color>
Cómo cambiar los colores del tema
Ahora que tienes recursos nuevos de color, puedes utilizarlos en tu tema.
- Abre
themes.xml
(res > values > themes > themes.xml). - Busca la sección
<!-- Primary brand color. -->
. - Agrega o cambia
colorPrimary
para usar@color/blue_500
. - Agrega o cambia
colorPrimaryVariant
para usar@color/blue_700
.
<item name="colorPrimary">@color/blue_500</item>
<item name="colorPrimaryVariant">@color/blue_700</item>
- Ejecuta la app. Deberías ver que el color de la barra de la app cambió y ahora es azul.
Cómo actualizar los colores del tema oscuro
Recomendamos que elijas más colores desaturados para el tema oscuro de la app.
- Abre el archivo
themes.xml
del tema oscuro (themes > themes.xml (night)). - Agrega o cambia los atributos del tema
colorPrimary
ycolorPrimaryVariant
de la siguiente manera:
<item name="colorPrimary">@color/blue_200</item>
<item name="colorPrimaryVariant">@color/blue_500</item>
- Ejecuta tu app.
- En la Configuración del dispositivo, activa el Tema oscuro.
- Tu app cambia al Tema oscuro. Verifica que se vea como en la siguiente captura de pantalla:
- En este punto, también puedes quitar los colores sin uso de tu archivo
colors.xml
(por ejemplo, los recursos de color púrpura que se usaron en el tema predeterminado de la app).
Cómo cambiar el ícono de la app
El último paso consiste en actualizar el ícono de la app.
- Descarga los archivos del ícono de la app
ic_launcher_foreground.xml
yic_launcher_background.xml
. Si tu navegador muestra el archivo en lugar de descargarlo, selecciona Archivo > Guardar página como… para guardarlo en tu computadora. - En Android Studio, borra dos archivos:
drawable/ic_launcher_background.xml
ydrawable-v24/ic_launcher_foreground.xml
, ya que son para el ícono de la app anterior. Puedes desmarcar la casilla Safe delete (with usage search). - Luego, haz clic con el botón derecho en la carpeta res > drawable y selecciona New > Image Asset.
- En la ventana Configure Image Asset, asegúrate de seleccionar Foreground layer.
- Debajo, busca la etiqueta Path.
- Haz clic en el ícono de la carpeta dentro del cuadro de texto Path.
- Busca y abre el archivo
ic_launcher_foreground.xml
que descargaste en la computadora.
- Cambia a la pestaña Background Layer.
- Haz clic en el ícono Browse, en el cuadro de texto Path.
- Busca y abre el archivo
ic_launcher_background.xml
en la computadora. No es necesario que hagas otros cambios. - Haz clic en Next.
- En el diálogo Confirm Icon Path, haz clic en Finish. Está bien que reemplaces los íconos existentes.
- Como práctica recomendada, puedes mover los nuevos elementos de diseño vectorial
ic_launcher_foreground.xml
yic_launcher_background.xml
a un nuevo directorio de recursos llamadodrawable-anydpi-v26
. Los íconos adaptables se introdujeron en la API 26, por lo que estos recursos solo se usarán en dispositivos que ejecuten la API 26 y versiones posteriores (para cualquier dpi). - Si ya no queda nada, borra el directorio
drawable-v24
. - Ejecuta tu app y observa el hermoso ícono de esta en el panel de apps.
- Como último paso, no olvides volver a cambiar el formato de los archivos Kotlin y XML en el proyecto para que tu código sea más limpio y cumpla con los lineamientos de estilo.
¡Felicitaciones! Creaste una app Affirmations inspiradora.
Con este conocimiento sobre cómo mostrar una lista de datos en una app para Android, ¿qué puedes compilar en el futuro?
4. Código de solución
El código de solución para la app Affirmations se encuentra en el siguiente repositorio de GitHub:
- Navega a la página de repositorio de GitHub del proyecto.
- Verifica que el nombre de la rama coincida con el especificado en el codelab. Por ejemplo, en la siguiente captura de pantalla, el nombre de la rama es main.
- En la página de GitHub de este proyecto, haz clic en el botón Code, el cual abre una ventana emergente.
- En la ventana emergente, haz clic en el botón Download ZIP para guardar el proyecto en tu computadora. Espera a que se complete la descarga.
- Ubica el archivo en tu computadora (probablemente en la carpeta Descargas).
- Haz doble clic en el archivo ZIP para descomprimirlo. Se creará una carpeta nueva con los archivos del proyecto.
Abre el proyecto en Android Studio
- Inicia Android Studio.
- En la ventana Welcome to Android Studio, haz clic en Open.
Nota: Si Android Studio ya está abierto, selecciona la opción de menú File > Open.
- En el navegador de archivos, ve hasta donde se encuentra la carpeta del proyecto descomprimida (probablemente en Descargas).
- Haz doble clic en la carpeta del proyecto.
- Espera a que Android Studio abra el proyecto.
- Haz clic en el botón Run para compilar y ejecutar la app. Asegúrate de que funcione como se espera.
5. Resumen
- Para mostrar contenido adicional en un elemento
RecyclerView
, modifica la clase del modelo de datos subyacente y la fuente de datos. Luego, actualiza el adaptador y el diseño del elemento de la lista para configurar esos datos en las vistas. - Usa las anotaciones de recursos para asegurarte de que el tipo de ID de recurso correcto se pase a un constructor de clase.
- Usa la biblioteca de componentes de Material Design para Android de modo que tu app siga con mayor facilidad los lineamientos de Material Design.
- Usa
MaterialCardView
para mostrar contenido en una tarjeta de Material. - Con algunos pequeños ajustes visuales en cuanto al color y los espacios, puedes lograr que la app luzca mejor y más coherente.
6. Más información
- Crea una lista con
RecyclerView
- Clase
RecyclerView
- Adaptadores
RecyclerView
RecyclerView
ViewHolder- Listas en Material Design
- Tarjetas en Material Design
MaterialCardView
- Cómo comenzar con los componentes de Material Design para Android
- Diseños de Android: comparación entre temas y estilos
- Íconos adaptables
7. Tarea de desafío
En esta serie de codelabs, aprendiste cómo usar LinearLayoutManager
con RecyclerView
. RecyclerView
puede usar diferentes LayoutManagers para diseñar datos de manera diferente.
- Cambia la propiedad
layoutManager
del elementoRecyclerView
aGridLayoutManager
. - Cambia la cantidad de columnas a 3.
- Cambia el diseño del adaptador para visualizar datos en una cuadrícula.