1. Introducción
Los componentes de Material (MDC) ayudan a los desarrolladores a implementar Material Design. MDC, creado por un equipo de ingenieros y diseñadores de UX en Google, cuenta con decenas de componentes de IU atractivos y funcionales, y está disponible para Android, iOS, la Web y Flutter.material.io/develop. |
En el codelab MDC-101, usaste dos componentes de Material (MDC) para crear una página de acceso: campos de texto y botones con ondas de tinta. Ahora vamos a agregar navegación, estructura y datos para expandir esta base.
Qué compilarás
En este codelab, compilarás una pantalla principal para una app llamada Shrine, una aplicación de comercio electrónico en la que se vende ropa y artículos para el hogar. Contiene lo siguiente:
- Una barra superior de la app
- Una lista de cuadrícula llena de productos
Componentes de MDC-Android en este codelab
- AppBarLayout
- MaterialCardView
Requisitos
- Conocimientos básicos de desarrollo de Android
- Android Studio (descárgalo aquí si todavía no lo tienes)
- Un emulador o dispositivo Android (disponible a través de Android Studio)
- El código de muestra (consulta el siguiente paso)
¿Cómo calificarías tu nivel de experiencia con la compilación de apps para Android?
2. Configura tu entorno de desarrollo
¿Vienes de MDC-101?
Si completaste MDC-101, tu código debería estar preparado para este codelab. Avanza al paso 3: Cómo agregar una barra superior de la app.
¿Empiezas de cero?
Descarga la app de inicio del codelab
La app de inicio se encuentra en el directorio material-components-android-codelabs-102-starter/kotlin
. Asegúrate de cd
en ese directorio antes de comenzar.
… o clónalo desde GitHub
Para clonar este codelab desde GitHub, ejecuta los siguientes comandos:
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 102-starter
Cómo cargar el código de inicio en Android Studio
- Una vez que finalice el asistente de configuración y aparezca la ventana Welcome to Android Studio, haz clic en Open an existing Android Studio project. Navega al directorio en el que instalaste el código de muestra y selecciona kotlin -> antiguo (o busca shrine) en tu computadora para abrir el proyecto de envío.
- Espera un momento para que Android Studio compile y sincronice el proyecto, como se muestra en los indicadores de actividad de la parte inferior de la ventana de Android Studio.
- En este punto, es posible que Android Studio genere algunos errores de compilación, ya que te faltan el SDK de Android o las herramientas de compilación, como se muestra más abajo. Sigue las instrucciones de Android Studio para instalar o actualizar estos elementos y sincronizar tu proyecto.
Agrega dependencias del proyecto
El proyecto necesita una dependencia en la biblioteca de compatibilidad de MDC para Android. El código de muestra que descargaste ya debería tener esta dependencia en la lista, pero te recomendamos que realices los siguientes pasos para asegurarte.
- Navega al archivo
build.gradle
del móduloapp
y asegúrate de que el bloquedependencies
incluya una dependencia en MDC para Android:
api 'com.google.android.material:material:1.1.0-alpha06'
- (Opcional) Si es necesario, edita el archivo
build.gradle
para agregar las siguientes dependencias y sincronizar el proyecto.
dependencies { api 'com.google.android.material:material:1.1.0-alpha06' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'com.android.volley:volley:1.1.1' implementation 'com.google.code.gson:gson:2.8.5' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:core:1.1.0' androidTestImplementation 'androidx.test.ext:junit:1.1.0' androidTestImplementation 'androidx.test:runner:1.2.0-alpha05' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05' }
Cómo ejecutar la app de inicio
|
¡Listo! Deberías ver la página de acceso de Shrine del codelab MDC-101.
Ahora que la pantalla de acceso se ve bien, vamos a propagar la app con algunos productos.
3. Cómo agregar una barra superior de la app
La pantalla principal se revela cuando se descarta la página de acceso, con una pantalla que dice "¡Lo lograste!". Fantástico. Pero ahora nuestro usuario no tiene ninguna acción para realizar ni sabe en qué parte de la app está. Para solucionarlo, es momento de agregar la navegación.
Material Design ofrece patrones de navegación que garantizan un alto grado de usabilidad. Uno de los componentes más visibles es la barra superior de la app.
Para posibilitar la navegación y brindar a los usuarios acceso rápido a otras acciones, agregaremos una barra superior de la app.
Cómo agregar un widget de AppBar
En shr_product_grid_fragment.xml
, borra el bloque <LinearLayout>
que contiene el mensaje "¡Lo lograste!". TextView
y reemplázalo por lo siguiente:
shr_product_grid_fragment.xml
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
Tu shr_product_grid_fragment.xml
ahora debería verse de la siguiente manera:
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
Muchas barras de la app tienen un botón junto al título. Agreguemos un ícono de menú al nuestro.
Cómo agregar un ícono de navegación
Aún en shr_product_grid_fragment.xml
, agrega lo siguiente al componente XML Toolbar
que acabas de agregar a tu diseño:
shr_product_grid_fragment.xml
app:navigationIcon="@drawable/shr_menu"
Tu shr_product_grid_fragment.xml
debería verse de la siguiente manera:
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
Cómo agregar botones de acción y diseñar la barra superior de la app
También puedes agregar botones en el extremo final de la barra de la app. En Android, estos se llaman botones de acción. Diseñaremos la barra superior de la app y agregaremos botones de acción a su menú de forma programática.
En la función onCreateView
de ProductGridFragment.kt
, configura el Toolbar
de activity
para que se use como ActionBar
con setSupportActionBar
. Puedes hacerlo después de que se haya creado la vista con el inflater
.
ProductGridFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
return view;
}
A continuación, justo debajo del método que acabamos de cambiar para configurar la barra de herramientas, anulemos onCreateOptionsMenu
para expandir el contenido de shr_toolbar_menu.xml
en la barra de herramientas:
ProductGridFragment.kt
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
Por último, anula onCreate()
en ProductGridFragment.kt
y, después de llamar a super()
, llama a setHasOptionMenu
con true
:
ProductGridFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
Los fragmentos de código anteriores configuran la barra de la app de nuestro diseño XML para que sea la barra de acciones de esta actividad. La devolución de llamada onCreateOptionsMenu
le indica a la actividad qué usar como menú. En este caso, colocará los elementos de menú de R.menu.shr_toolbar_menu
en la barra de la app. El archivo de menú contiene dos elementos: "Buscar" y "Filtro".
shr_toolbar_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/shr_search"
android:title="@string/shr_search_title"
app:showAsAction="always" />
<item
android:id="@+id/filter"
android:icon="@drawable/shr_filter"
android:title="@string/shr_filter_title"
app:showAsAction="always" />
</menu>
Después de esos cambios, tu archivo ProductGridFragment.kt
debería verse de la siguiente manera:
ProductGridFragment.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*
class ProductGridFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the tool bar
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
return view;
}
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
}
Realiza la compilación y ejecuta la aplicación. La pantalla principal debería verse de la siguiente manera:
Ahora la barra de herramientas tiene un ícono de navegación, un título y dos íconos de acción en el lado derecho. La barra de herramientas también muestra la elevación con una sombra sutil que indica que se encuentra en una capa diferente a la del contenido.
4. Agregar una tarjeta
Ahora que nuestra app tiene cierta estructura, coloquemos el contenido en tarjetas para organizarlo.
Agregar una tarjeta
Comencemos por agregar una tarjeta debajo de la barra superior de la app. Una tarjeta debe tener una región para una imagen, un título y una etiqueta para el texto secundario. Agrega lo siguiente en shr_product_grid_fragment.xml
debajo de AppBarLayout
.
shr_product_grid_fragment.xml
<com.google.android.material.card.MaterialCardView
android:layout_width="160dp"
android:layout_height="180dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="70dp"
app:cardBackgroundColor="?attr/colorPrimaryDark"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Compila y ejecuta:
En esta vista previa, puedes ver que la tarjeta está insertada desde el borde izquierdo y tiene esquinas redondeadas y una sombra (que expresa la elevación de la tarjeta). Todo el elemento se denomina "contenedor". Aparte del contenedor, todos los elementos que contiene son opcionales.
Puedes agregar los siguientes elementos a un contenedor: texto de encabezado, una miniatura o un avatar, texto de subtítulo, divisores y hasta íconos y botones. Por ejemplo, la tarjeta que acabamos de crear contiene dos TextView
(uno para el título y otro para el texto secundario) en un LinearLayout
, alineado con la parte inferior de la tarjeta.
Las tarjetas suelen mostrarse en una colección con otras tarjetas. En la siguiente sección de este codelab, los presentaremos como una colección en una cuadrícula.
5. Crea una cuadrícula de tarjetas
Cuando hay varias tarjetas en una pantalla, se agrupan en una o más colecciones. Las tarjetas en una cuadrícula son coplanares, lo que significa que comparten la misma elevación en reposo que las demás (a menos que se recojan o arrastren, pero no abordaremos eso en este codelab).
Configura la cuadrícula de tarjetas
Consulta el archivo shr_product_card.xml
que te proporcionamos:
shr_product_card.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/white"
app:cardElevation="2dp"
app:cardPreventCornerOverlap="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/product_image"
android:layout_width="match_parent"
android:layout_height="@dimen/shr_product_card_image_height"
android:background="?attr/colorPrimaryDark"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/product_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:id="@+id/product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Este diseño de tarjeta contiene una tarjeta con una imagen (en este caso, un NetworkImageView
, que nos permite cargar y mostrar imágenes desde una URL) y dos TextViews
.
A continuación, observa el ProductCardRecyclerViewAdapter
que te proporcionamos. Está en el mismo paquete que ProductGridFragment
.
ProductCardRecyclerViewAdapter.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
/**
* Adapter used to show a simple grid of products.
*/
class ProductCardRecyclerViewAdapter(private val productList: List<ProductEntry>) : RecyclerView.Adapter<ProductCardViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductCardViewHolder {
val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.shr_product_card, parent, false)
return ProductCardViewHolder(layoutView)
}
override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
// TODO: Put ViewHolder binding code here in MDC-102
}
override fun getItemCount(): Int {
return productList.size
}
}
La clase de adaptador anterior administra el contenido de nuestra cuadrícula. Para determinar qué debe hacer cada vista con su contenido determinado, pronto escribiremos el código de onBindViewHolder()
.
En el mismo paquete, también puedes observar ProductCardViewHolder
. Esta clase almacena las vistas que afectan el diseño de nuestra tarjeta, de modo que podamos modificarlas más adelante.
package com.google.codelabs.mdc.kotlin.shrine
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class ProductCardViewHolder(itemView: View) //TODO: Find and store views from itemView
: RecyclerView.ViewHolder(itemView)
Para configurar nuestra cuadrícula, primero debemos quitar el marcador de posición MaterialCardView
de shr_product_grid_fragment.xml
. A continuación, debes agregar el componente que representa nuestra cuadrícula de tarjetas. En este caso, usaremos un RecyclerView. Agrega el componente RecyclerView a tu shr_product_grid_fragment.xml
debajo del componente XML AppBarLayout
:
shr_product_grid_fragment.xml
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
Tu shr_product_grid_fragment.xml
debería verse de la siguiente manera:
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
</FrameLayout>
Por último, en onCreateView()
, agrega el código de inicialización de RecyclerView
a ProductGridFragment.kt
después de llamar a setUpToolbar(view)
y antes de la sentencia return
:
ProductGridFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
// Set up the RecyclerView
view.recycler_view.setHasFixedSize(true)
view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
val adapter = ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(resources))
view.recycler_view.adapter = adapter
val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
view.recycler_view.addItemDecoration(ProductGridItemDecoration(largePadding, smallPadding))
return view;
}
El fragmento de código anterior contiene los pasos de inicialización necesarios para configurar un RecyclerView
. Esto incluye la configuración del administrador de diseño de RecyclerView
, además de la inicialización y la configuración del adaptador de RecyclerView
.
Tu archivo ProductGridFragment.kt
ahora debería verse de la siguiente manera:
ProductGridFragment .kt
package com.google.codelabs.mdc.kotlin.shrine
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*
class ProductGridFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
// Set up the RecyclerView
view.recycler_view.setHasFixedSize(true)
view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
val adapter = ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(resources))
view.recycler_view.adapter = adapter
val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
view.recycler_view.addItemDecoration(ProductGridItemDecoration(largePadding, smallPadding))
return view;
}
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
}
Compila y ejecuta:
Las tarjetas ya están allí. Aún no muestran nada, así que agreguemos algunos datos de productos.
Agrega imágenes y texto
Para cada tarjeta, agrega una imagen, el nombre del producto y el precio. Nuestra abstracción ViewHolder
contiene las vistas de cada tarjeta. En nuestro ViewHolder
, agrega las tres vistas de la siguiente manera.
ProductCardViewHolder.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.toolbox.NetworkImageView
class ProductCardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var productImage: NetworkImageView = itemView.findViewById(R.id.product_image)
var productTitle: TextView = itemView.findViewById(R.id.product_title)
var productPrice: TextView = itemView.findViewById(R.id.product_price)
}
Actualiza el método onBindViewHolder()
en ProductCardRecyclerViewAdapter
para establecer el título, el precio y la imagen del producto para cada vista de producto, como se muestra a continuación:
ProductCardRecyclerViewAdapter.kt
override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
if (position < productList.size) {
val product = productList[position]
holder.productTitle.text = product.title
holder.productPrice.text = product.price
ImageRequester.setImageFromUrl(holder.productImage, product.url)
}
}
El código anterior le indica a nuestro adaptador de RecyclerView
qué hacer con cada tarjeta mediante un ViewHolder
.
Aquí, establece los datos de texto en cada uno de los TextView
de ViewHolder
y llama a un ImageRequester
para obtener una imagen de una URL. ImageRequester
es una clase que proporcionamos para tu comodidad y usa la biblioteca Volley
(este es un tema fuera del alcance de este codelab, pero no dudes en explorar el código por tu cuenta).
Compilación y ejecución:
Nuestros productos ya se muestran en la app.
6. Resumen
Nuestra app tiene un flujo básico que lleva al usuario de la pantalla de acceso a una pantalla principal en la que se pueden ver los productos. Con solo unas pocas líneas de código, agregamos una barra superior de la app con un título y tres botones, y una cuadrícula de tarjetas para presentar el contenido de nuestra app. Ahora, la pantalla principal es simple y funcional, y tiene una estructura básica y contenido de acción.
Próximos pasos
Con la barra superior de la app, las tarjetas, el campo de texto y el botón, ahora usamos cuatro componentes principales de Material Design de la biblioteca de MDC-Android. Puedes visitar el catálogo de MDC-Android para explorar aún más componentes.
Aunque funciona en su totalidad, nuestra app aún no expresa ninguna marca ni estilo en particular. En MDC-103: Temas de Material Design con color, forma, elevación y tipo, personalizaremos el estilo de estos componentes para expresar una marca moderna y llamativa.