Para comenzar a proporcionar tarjetas de tu app, incluye las siguientes dependencias en el archivo build.gradle
.
Groovy
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.5.0" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.3.0" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.3.0" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.3.0" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.5.0" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.5.0" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.5.0") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.3.0") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.3.0") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.3.0") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.5.0") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.5.0") }
Conceptos clave
Las tarjetas no se compilan de la misma manera que las apps para Android y utilizan diferentes conceptos:
- Plantillas de diseño: Definen la disposición general de los elementos visuales en la pantalla. Esto se logra con la función
primaryLayout()
. - Elementos de diseño: Representan un elemento gráfico individual, como un botón o una tarjeta, o varios de estos elementos agrupados con una columna, un grupo de botones o un elemento similar. Estos se incorporan en una plantilla de diseño.
- Recursos: Los objetos
ResourceBuilders.Resources
constan de un map de pares clave-valor de los recursos de Android (imágenes) que se requieren para renderizar un diseño y una versión. - Línea de tiempo: Un objeto
TimelineBuilders.Timeline
es una lista de una o más instancias de un objeto de diseño. Puedes proporcionar varios mecanismos y expresiones para indicar cuándo el renderizador debe cambiar de un objeto de diseño a otro, por ejemplo, para dejar de mostrar un diseño en un momento específico. - Estado: Es una estructura de datos de tipo
StateBuilders.State
que se pasa entre la tarjeta y la app para permitir que los dos componentes se comuniquen entre sí. Por ejemplo, si se presiona un botón en la tarjeta, el estado contiene el ID del botón. También puedes intercambiar tipos de datos con un mapa. - Tile: Es un objeto
TileBuilders.Tile
que representa una tarjeta y que consta de una línea de tiempo, un ID de versión de recursos, un intervalo de actualización y un estado. - Protolayout: Este término aparece en el nombre de varias clases relacionadas con tarjetas y hace referencia a la biblioteca de Protolayout de Wear OS, una biblioteca de gráficos que se usa en varias plataformas de Wear OS.
Cómo crear una tarjeta
Para proporcionar una tarjeta desde tu app, implementa un servicio de tipo TileService
y regístralo en tu manifiesto. A partir de esto, el sistema solicita las tiles necesarias durante las llamadas a onTileRequest()
y los recursos durante las llamadas a onTileResourcesRequest()
.
class MyTileService : TileService() { override fun onTileRequest(requestParams: RequestBuilders.TileRequest) = Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( materialScope(this, requestParams.deviceConfiguration) { primaryLayout( mainSlot = { text("Hello, World!".layoutString, typography = BODY_LARGE) } ) } ) ) .build() ) override fun onTileResourcesRequest(requestParams: ResourcesRequest) = Futures.immediateFuture( Resources.Builder().setVersion(RESOURCES_VERSION).build() ) }
A continuación, agrega un servicio dentro de la etiqueta <application>
de tu archivo AndroidManifest.xml
.
<service android:name=".snippets.m3.tile.MyTileService" android:label="@string/tile_label" android:description="@string/tile_description" android:icon="@mipmap/ic_launcher" android:exported="true" android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER"> <intent-filter> <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" /> </intent-filter> <meta-data android:name="androidx.wear.tiles.PREVIEW" android:resource="@drawable/tile_preview" /> </service>
El filtro de intents y permisos registra este servicio como un proveedor de tarjetas.
El ícono, la etiqueta, la descripción y el recurso de vista previa se muestran al usuario cuando este configura tarjetas en su teléfono o reloj. Ten en cuenta que el recurso de vista previa admite todos los calificadores de recursos estándar de Android, por lo que es posible variar la vista previa según factores como el tamaño de la pantalla y el idioma del dispositivo. Consulta la lista de verificación de la vista previa para obtener recomendaciones adicionales.
Implementa tu app y agrega la tarjeta al carrusel de tarjetas (también hay una forma más sencilla para los desarrolladores de obtener una vista previa de una tarjeta, pero, por ahora, hazlo de forma manual).

Para ver un ejemplo completo, consulta la muestra de código en GitHub o el codelab.
Cómo crear una IU para tarjetas
Los elementos de la IU expresiva de Material 3 se crean con un enfoque estructurado basado en el patrón de compilador de acceso seguro a tipos de Kotlin.
Diseño
Para obtener orientación sobre los principios de diseño que se aplican a la creación de diseños de tarjetas eficaces y responsivos, consulta Diseños comunes para tarjetas.
Para crear tu diseño, haz lo siguiente:
Inicia un alcance de Material Design: Llama a la función
materialScope()
y proporciona los elementoscontext
ydeviceConfiguration
necesarios. Puedes incluir parámetros opcionales, comoallowDynamicTheme
ydefaultColorScheme
. El valor predeterminado deallowDynamicTheme
estrue
, ydefaultColorScheme
representa elColorScheme
que se usa cuando los colores dinámicos no están disponibles (por ejemplo, cuando el usuario desactivó la función o cuando el dispositivo no la admite, o bienallowDynamicTheme
esfalse
).Compila tu IU dentro del alcance: Todos los componentes de la IU para un diseño de tarjeta determinado deben definirse dentro de la expresión lambda de una sola llamada de nivel superior materialScope(). Estas funciones de componentes, como
primaryLayout()
ytextEdgeButton()
, son funciones de extensión enMaterialScope
y solo están disponibles cuando se las llama en este alcance del receptor.materialScope( context = context, deviceConfiguration = requestParams.deviceConfiguration, // requestParams is passed to onTileRequest defaultColorScheme = myFallbackColorScheme ) { // inside the MaterialScope, you can call functions like primaryLayout() primaryLayout( titleSlot = { text(text = "Title".layoutString) }, mainSlot = { text(text = "Main Content".layoutString) }, bottomSlot = { textEdgeButton(text = "Action".layoutString) } ) }
Máquinas tragamonedas
En M3, el diseño de tarjetas usa un enfoque inspirado en Compose que utiliza tres ranuras distintas. De arriba hacia abajo, son los siguientes:
- Es el
titleSlot
, por lo general, para un título o encabezado principal. - Es el
mainSlot
del contenido principal. - El
bottomSlot
, que se suele usar para acciones o información complementaria. Aquí también aparece un botón de borde.

El contenido de cada ranura es el siguiente:
titleSlot
(opcional): Por lo general, son algunas palabras que generatext()
.mainSlot
(obligatorio): Componentes organizados en estructuras como filas, columnas y grupos de botones. Estos componentes también se pueden incorporar de forma recursiva entre sí; por ejemplo, una columna puede contener filas.bottomSlot
(opcional): Por lo general, se completa con un botón que se ajusta al borde o una etiqueta de texto.
Como no se pueden desplazar los mosaicos, no hay componentes para la paginación, el desplazamiento ni el control de listas largas de contenido. Asegúrate de que el contenido siga siendo visible cuando aumente el tamaño de la fuente o el texto se alargue debido a la traducción.
Componentes de IU
La biblioteca de protolayout-material3
proporciona una gran cantidad de componentes diseñados según las especificaciones de Material 3 Expressive y las recomendaciones de la interfaz de usuario.
Botones
Los botones están principalmente orientados a la acción. Sirven para activar acciones específicas. El contenido de cada botón, como un ícono o un texto corto, identifica la acción.
- textButton(): Botón con una sola ranura para contenido de texto (corto)
- iconButton(): Botón con una sola ranura para representar un ícono
- avatarButton(): Es un botón de avatar en forma de píldora que ofrece hasta tres espacios para incluir contenido que represente una etiqueta apilada verticalmente y una etiqueta secundaria, y una imagen (avatar) junto a ellas.
- imageButton(): Es un botón de imagen en el que se puede hacer clic y que no ofrece ranuras adicionales, solo imágenes (por ejemplo, backgroundImage como fondo).
- compactButton(): Botón compacto que ofrece hasta dos ranuras para incluir contenido apilado horizontalmente que representa un ícono y texto junto a él
- button(): Es un botón con forma de píldora que ofrece hasta tres ranuras para incluir contenido que represente una etiqueta y una etiqueta secundaria apiladas verticalmente, y un ícono junto a ellas.
Botones de borde
Un botón de borde es un botón especializado de ancho completo anclado en la parte inferior de la pantalla redonda de un reloj, que representa la acción más importante que se debe realizar desde la pantalla de la tarjeta actual.
- iconEdgeButton(): Es un botón de borde que ofrece una sola ranura para introducir un ícono o contenido pequeño y redondo similar.
- textEdgeButton(): Es un botón de borde que ofrece una sola ranura para incluir texto o contenido similarmente largo y ancho.
Tarjetas
Las tarjetas son principalmente informativas. Muestran colecciones de datos estructurados relacionados. Si bien puedes crear tarjetas interactivas, suelen mostrar un resumen de la información, en el que el usuario puede presionar para ver más detalles o realizar una acción relacionada.
- titleCard(): Tarjeta de título que ofrece de una a tres ranuras, por lo general, basadas en texto
- appCard(): Tarjeta de la app que ofrece hasta cinco espacios, generalmente basados en texto
- textDataCard(): Tarjeta de datos que ofrece hasta tres ranuras apiladas verticalmente, por lo general, basadas en texto o números
- iconDataCard(): Tarjeta de datos que ofrece hasta tres ranuras apiladas verticalmente, por lo general, basadas en texto o números, con un ícono
- graphicDataCard(): Tarjeta de datos gráficos que ofrece un espacio para datos gráficos, como un indicador de progreso, y hasta dos espacios apilados verticalmente, generalmente para descripciones de texto
Indicadores de progreso
- circularProgressIndicator(): Indica el progreso hacia un objetivo con un elemento radial.
- segmentedCircularProgressIndicator(): Indica el progreso hacia un objetivo con un elemento radial con etapas distintas.
Cómo agrupar elementos de diseño
- buttonGroup(): Diseño de componente que coloca sus elementos secundarios en una secuencia horizontal
- primaryLayout(): Diseño de pantalla completa que representa un diseño de M3 sugerido que es responsivo y se encarga de la ubicación de los elementos, junto con los márgenes y el padding recomendados aplicados
Temas
En Material 3 Expressive, el sistema de color se define con 29 roles de color estándar, organizados en seis grupos: primario, secundario, terciario, error, superficie y contorno.

Un ColorScheme
asigna cada uno de estos 29 roles a un color correspondiente y, como forma parte de MaterialScope
y los componentes deben crearse dentro de él, automáticamente toman colores del esquema. Este enfoque permite que todos los elementos de la IU se ajusten automáticamente a los estándares de Material Design.
Para permitir que los usuarios elijan entre un esquema de color que definas (por ejemplo, uno que refleje los colores de tu marca) y uno proporcionado por el sistema (derivado de la cara del reloj actual del usuario o uno elegido por el usuario), inicializa MaterialScope
de la siguiente manera:
val myColorScheme =
ColorScheme(
primary = ...
onPrimary = ...
// 27 more
)
materialScope(
defaultColorScheme = myColorScheme
) {
// If the user selects "no theme" in settings, myColorScheme is used.
// Otherwise, the system-provided theme is used.
}
Para forzar que tus tarjetas aparezcan en el esquema de color que proporcionas, inhabilita la compatibilidad con la creación de temas dinámicos configurando allowDynamicTheme
como false
:
materialScope(
allowDynamicTheme = false,
defaultColorScheme = myColorScheme
) {
// myColorScheme is *always* used.
}
Color
Cada componente individual usa un subconjunto de los 29 roles de color definidos por un ColorScheme
. Por ejemplo, los botones usan hasta cuatro colores, que, de forma predeterminada, se toman del grupo "principal" del ColorScheme
activo:
Token del componente ButtonColors |
Rol de ColorScheme |
---|---|
containerColor | primary |
iconColor | onPrimary |
labelColor | onPrimary |
secondaryLabelColor | onPrimary (opacidad 0.8) |
Para obtener orientación detallada sobre cómo aplicar color a tus diseños de Wear OS, consulta la guía de diseño de color.
Es posible que debas desviarte de los tokens de color predeterminados para elementos específicos de la IU. Por ejemplo, es posible que desees que un textEdgeButton
use colores del grupo "secundario" o "terciario", en lugar de "primario", para destacarse y brindar un mejor contraste.
Puedes personalizar los colores de los componentes de varias maneras:
Usa una función auxiliar para los colores predefinidos. Usa funciones auxiliares como
filledTonalButtonColors()
para aplicar los diseños de botones estándar de Material 3 Expressive. Estas funciones crean instancias deButtonColors
preconfiguradas que asignan estilos comunes, como rellenado, tonal o delineado, a los roles adecuados delColorScheme
activo dentro delMaterialScope
. Esto te permite aplicar estilos coherentes sin definir manualmente cada color para los tipos de botones comunes.textEdgeButton( colors = filledButtonColors() // default /* OR colors = filledTonalButtonColors() */ /* OR colors = filledVariantButtonColors() */ // ... other parameters )
Para las tarjetas, usa la familia de funciones
filledCardColors()
equivalente.También puedes modificar el objeto
ButtonColors
que muestran las funciones de ayuda con su métodocopy()
si solo necesitas cambiar uno o dos tokens:textEdgeButton( colors = filledButtonColors() .copy( containerColor = colorScheme.tertiary, labelColor = colorScheme.onTertiary ) // ... other parameters )
Proporciona explícitamente roles de color de reemplazo. Crea tu propio objeto
ButtonColors
y pásalo al componente. Para las tarjetas, usa el objetoCardColors
equivalente.textEdgeButton( colors = ButtonColors( // the materialScope makes colorScheme available containerColor = colorScheme.secondary, iconColor = colorScheme.secondaryDim, labelColor = colorScheme.onSecondary, secondaryLabelColor = colorScheme.onSecondary ) // ... other parameters )
Especifica colores fijos (usar con precaución). Si bien, en general, se recomienda especificar los colores por su rol semántico (p.ej.,
colorScheme.primary
), también puedes proporcionar valores de color directos. Este enfoque debe usarse con moderación, ya que puede generar incoherencias con el tema general, especialmente si el tema cambia de forma dinámica.textEdgeButton( colors = filledButtonColors().copy( containerColor = android.graphics.Color.RED.argb, // Using named colors labelColor = 0xFFFFFF00.argb // Using a hex code for yellow ) // ... other parameters )
Tipografía
Para obtener más información sobre el uso eficaz de la tipografía en tus diseños, consulta la guía de diseño de tipografía.
Para crear coherencia visual en toda la plataforma de Wear OS y optimizar el rendimiento, todo el texto de las tarjetas se renderiza con una fuente proporcionada por el sistema. Es decir, las tarjetas no admiten tipos de letra personalizados. En Wear OS 6 y versiones posteriores, esta es una fuente específica del OEM. En la mayoría de los casos, será una fuente variable, que ofrece una experiencia más expresiva y un control más detallado.
Para crear un estilo de texto, generalmente usas el método text()
combinado con constantes tipográficas. Este componente te permite usar roles de tipografía predefinidos en Material 3 Expressive, lo que ayuda a que tu tarjeta cumpla con las prácticas recomendadas de tipografía establecidas para la legibilidad y la jerarquía.
La biblioteca ofrece un conjunto de 18 constantes de tipografía semántica, como BODY_MEDIUM. Estas constantes también afectan a otros ejes de la fuente además del tamaño.
text(
text = "Hello, World!".layoutString,
typography = BODY_MEDIUM,
)
Para obtener más control, puedes proporcionar parámetros de configuración adicionales. En Wear OS 6 y versiones posteriores, es probable que se use una fuente variable, que puedes modificar a lo largo de los ejes cursiva, grosor, ancho y redondez. Puedes controlar estos ejes con el parámetro settings
:
text(
text = "Hello, World".layoutString,
italic = true,
// Use elements defined in androidx.wear.protolayout.LayoutElementBuilders.FontSetting
settings =
listOf(weight(500), width(100F), roundness(100)),
)
Por último, si necesitas controlar el tamaño o el espaciado entre letras (no recomendado), usa basicText() en lugar de text() y crea un valor para la propiedad fontStyle
con fontStyle().
Forma y márgenes
Puedes cambiar el radio de esquina de casi todos los componentes con su propiedadshape
. Los valores provienen de la propiedad MaterialScope
shapes
:
textButton(
height = expand(),
width = expand(),
shape = shapes.medium, // OR another value like shapes.full
colors = filledVariantButtonColors(),
labelContent = { text("Hello, World!".layoutString) },
)
Después de modificar la forma de un componente, si crees que deja demasiado o muy poco espacio alrededor del borde de la pantalla, ajusta los márgenes con el parámetro margin
de primaryLayout()
:
primaryLayout(
mainSlot = {
textButton(
shape = shapes.small,
/* ... */
)
},
// margin constants defined in androidx.wear.protolayout.material3.PrimaryLayoutMargins
margins = MAX_PRIMARY_LAYOUT_MARGIN,
)
Arcos
Se admiten los siguientes contenedores secundarios de Arc
:
ArcLine
: Renderiza una línea curva alrededor del arco.ArcText
: Renderiza el texto curvo en el arco.ArcAdapter
: Renderiza un elemento de diseño básico en el arco, dibujado en una tangente al arco.
Para obtener más información, consulta la documentación de referencia de cada uno de los tipos de elementos.
Modificadores
De manera opcional, a cada elemento de diseño disponible se le pueden aplicar modificadores. Usa estos modificadores con los siguientes fines:
- Cambia la apariencia visual del diseño. Por ejemplo, agrega un fondo, un borde o un padding al elemento de diseño.
- Agrega metadatos sobre el diseño. Por ejemplo, agrega un modificador de semántica a tu elemento de diseño para usarlo con lectores de pantalla.
- Agrega funcionalidad. Por ejemplo, agrega un modificador en el que se pueda hacer clic a tu elemento de diseño para que la tarjeta sea interactiva. Para obtener más información, consulta el artículo sobre interacciones con tarjetas.
Por ejemplo, podemos personalizar el aspecto y los metadatos predeterminados de un Image
, como se muestra en la siguiente muestra de código:
Kotlin
private fun myImage(): LayoutElement = Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(Modifiers.Builder() .setBackground(Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(Padding.Builder().setStart(dp(12f)).build()) .setSemantics(Semantics.builder() .setContentDescription("Image description") .build() ).build() ).build()
Java
private LayoutElement myImage() { return new Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(new Modifiers.Builder() .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(new Padding.Builder().setStart(dp(12f)).build()) .setSemantics(new Semantics.Builder() .setContentDescription("Image description") .build() ).build() ).build(); }
Spannables
Un Spannable
es un tipo especial de contenedor que presenta los elementos de manera similar al texto. Es útil cuando deseas aplicar un estilo diferente a una sola subcadena en un bloque de texto más grande, lo que no es posible con el elemento Text
.
Un contenedor Spannable
se llena con elementos secundarios Span
. No se permiten otras instancias secundarias ni instancias Spannable
anidadas.
Hay dos tipos de elementos Span
secundarios:
SpanText
: Renderiza texto con un estilo específico.SpanImage
: Renderiza una imagen intercalada con texto.
Por ejemplo, puedes escribir "world" en cursiva en una tarjeta "Hello world" e insertar una imagen entre las palabras, como se muestra en el siguiente ejemplo de código:
Kotlin
private fun mySpannable(): LayoutElement = Spannable.Builder() .addSpan(SpanText.Builder() .setText("Hello ") .build() ) .addSpan(SpanImage.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .build() ) .addSpan(SpanText.Builder() .setText("world") .setFontStyle(FontStyle.Builder() .setItalic(true) .build()) .build() ).build()
Java
private LayoutElement mySpannable() { return new Spannable.Builder() .addSpan(new SpanText.Builder() .setText("Hello ") .build() ) .addSpan(new SpanImage.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .build() ) .addSpan(new SpanText.Builder() .setText("world") .setFontStyle(newFontStyle.Builder() .setItalic(true) .build()) .build() ).build(); }
Cómo trabajar con recursos
Las tarjetas no tienen acceso a ningún recurso de tu app, lo que significa que no puedes pasar el ID de una imagen de Android a un elemento de diseño Image
y esperar que se resuelva. En cambio, anula el método onTileResourcesRequest()
y proporciona los recursos de forma manual.
Existen dos maneras de brindar imágenes dentro del método onTileResourcesRequest()
:
- Brinda un recurso de elementos de diseño con
setAndroidResourceByResId()
. - Brinda una imagen dinámica como un elemento
ByteArray
consetInlineResource()
.
Kotlin
override fun onTileResourcesRequest( requestParams: ResourcesRequest ) = Futures.immediateFuture( Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", ImageResource.Builder() .setAndroidResourceByResId(AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", ImageResource.Builder() .setInlineResource(InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() )
Java
@Override protected ListenableFuture<Resources> onTileResourcesRequest( @NonNull ResourcesRequest requestParams ) { return Futures.immediateFuture( new Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", new ImageResource.Builder() .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", new ImageResource.Builder() .setInlineResource(new InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() ); }
Lista de tareas de la imagen de vista previa de la tarjeta
El sistema muestra la imagen de vista previa de la tarjeta, a la que se hace referencia en el manifiesto de la app para Android, en el editor del carrusel de tarjetas para agregar una tarjeta nueva. Este editor aparece tanto en los dispositivos Wear OS como en la app complementaria del reloj en los teléfonos.
Para ayudar a los usuarios a aprovechar al máximo esta imagen de vista previa, verifica los siguientes detalles sobre tu tarjeta:
- Refleja el diseño más reciente. La vista previa debe representar con precisión el diseño más actual de tu tarjeta.
- Usa dimensiones recomendadas. Para proporcionar la mejor calidad de visualización posible y una buena experiencia del usuario, la imagen de vista previa debe tener dimensiones de 400 px por 400 px.
- Usa un tema de color estático. Usar el tema de color estático de la tarjeta, no uno dinámico
- Incluye el ícono de la app. Confirma que el ícono de tu app aparezca en la parte superior de la imagen de vista previa.
- Muestra el estado de carga o acceso. La vista previa debe mostrar un estado "cargado" o "conectado" completamente funcional, sin contenido vacío ni de marcador de posición.
- Aprovecha las reglas de resolución de recursos para la personalización (opcional). Considera usar las reglas de resolución de recursos de Android para proporcionar vistas previas que coincidan con la configuración de tamaño de pantalla, idioma o configuración regional del dispositivo. Esto es especialmente útil si la apariencia de la tarjeta varía según el dispositivo.