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.6.2" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.4.2" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.4.2" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.4.2" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.6.2" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.6.2" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.6.2") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.4.2") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.4.2") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.4.2") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.6.2") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.6.2") }
Conceptos clave
Las tarjetas no se compilan de la misma manera que las apps para Android y usan conceptos diferentes:
- 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 esos elementos agrupados con una columna, un buttonGroup o un elemento similar. Se incorporan en una plantilla de diseño.
- Recursos: Los objetos
ResourceBuilders.Resourcesconstan de un mapa de pares clave-valor de los recursos de Android (imágenes) que se requieren para renderizar un diseño y una versión. - Cronograma: Un objeto
TimelineBuilders.Timelinees 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, como dejar de mostrar un diseño en un momento específico. - Estado: Es una estructura de datos de tipo
StateBuilders.Stateque 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. - Mosaico: Es un objeto
TileBuilders.Tileque representa un mosaico, que consta de un cronograma, 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 las 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
Usa Material3TileService (recomendado)
Cuando compiles tarjetas de Material 3 (androidx.wear.tiles:tiles:1.6.0 y versiones posteriores), extiende siempre Material3TileService en lugar de la clase TileService de nivel inferior. Material3TileService proporciona una arquitectura centrada en Kotlin que simplifica el desarrollo de tarjetas:
- Corrutinas de Kotlin integradas: Implementa una sola función
MaterialScope.tileResponse(requestParams: TileRequest): Tilede suspensión en lugar de usarListenableFuturey anularonTileRequest(). MaterialScopepreconfigurado:tileResponse()se ejecuta conMaterialScopecomo su receptor (configurado a través de parámetros del constructor, comoallowDynamicThemeydefaultColorScheme), por lo que no necesitas unir tu diseño en una llamada redundante amaterialScope().- Registro de recursos de llamada única: Incluye
ProtoLayoutScopepara registrar automáticamente los recursos de imagen intercalados y devolver el diseño de la tarjeta y los recursos en una sola llamada de Binder del sistema. Debido a queMaterial3TileServicecontrola los recursos automáticamente (finalonTileResourcesRequest()), no anulesonTileResourcesRequest().
class MyTileService : Material3TileService() { override suspend fun MaterialScope.tileResponse(requestParams: TileRequest): Tile = tile( timeline = Timeline.fromLayoutElement( primaryLayout( mainSlot = { text("Hello, World!".layoutString, typography = BODY_LARGE) } ) ) ) }
Arquitectura de TileService subyacente
Material3TileService se basa en la clase base TileService,
que usan los ejemplos restantes de esta guía para ilustrar conceptos de bajo nivel.
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 tarjetas 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> del 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 tareas 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 fácil 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 de Material 3 Expressive se crean con un enfoque estructurado potenciado por el patrón de compilador con seguridad de tipos de Kotlin.
Diseño
Si quieres obtener orientación sobre los principios de diseño que se deben tener en cuenta para crear 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 valorescontextydeviceConfigurationobligatorios. Puedes incluir parámetros opcionales, comoallowDynamicThemeydefaultColorScheme.allowDynamicThemeestruede forma predeterminada, ydefaultColorSchemerepresenta elColorSchemeque se usa cuando los colores dinámicos no están disponibles (por ejemplo, cuando el usuario desactivó la función), cuando el dispositivo no lo admite o cuandoallowDynamicThemeesfalse). Cuando uses las APIs deImageResource, comobackgroundImage(), en unTileServicepersonalizado, llama amaterialScopeWithResources().Compila tu IU dentro del alcance: Todos los componentes de la IU para un diseño de tarjeta determinado se deben definir dentro de la expresión lambda de una sola llamada a materialScope() de nivel superior. Estas funciones de componentes, como
primaryLayout()ytextEdgeButton(), son funciones de extensión enMaterialScopey 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( labelContent = { text("Action".layoutString) }, onClick = clickable() ) } ) }
Ranuras
En M3, el diseño de tarjetas usa un enfoque inspirado en Compose que utiliza tres ranuras distintas. De arriba hacia abajo, son las siguientes:
- El
titleSlot, que suele usarse para un título o encabezado principal. mainSlot, para el contenido principal- El
bottomSlot, que suele usarse 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 generadas portext().mainSlot(obligatorio): Son componentes organizados en estructuras, como filas, columnas y grupos de botones. Estos componentes también se pueden incorporar de forma recurrente 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 puede desplazar por las tarjetas, no hay componentes para paginar, desplazar o controlar 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 extienda debido a la traducción.
Componentes de IU
La biblioteca de protolayout-material3 proporciona una gran cantidad de componentes diseñados de acuerdo con 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 breve, identifica la acción.
- textButton(): Es un botón con una sola ranura para contenido de texto (corto).
- iconButton(): Es un botón con una sola ranura para representar un ícono.
- avatarButton(): Es un botón de avatar con forma de píldora que ofrece hasta tres ranuras para incluir contenido que represente una etiqueta y una etiqueta secundaria apiladas verticalmente, 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 una imagen (por ejemplo,
backgroundImagecomo fondo). - compactButton(): Es un botón compacto que ofrece hasta dos ranuras para incluir contenido apilado de forma horizontal 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 perimetrales
Un botón de borde es un botón especializado de ancho completo que se fija en la parte inferior de la pantalla redonda de un reloj y representa la acción más importante que se debe realizar desde la pantalla de tarjetas actual.
- iconEdgeButton(): Es un botón de borde que ofrece una sola ranura para introducir un ícono o contenido pequeño similarmente redondo.
- textEdgeButton(): Es un botón de borde que ofrece una sola ranura para incluir un texto o un contenido similarmente largo y ancho.
Tarjetas
Las tarjetas están principalmente orientadas a la información. Muestran colecciones de datos estructurados relacionados. Si bien puedes crear tarjetas interactivas, estas suelen mostrar un resumen de la información, que el usuario puede presionar para ver más detalles o realizar una acción relacionada.
- titleCard(): Tarjeta de título que ofrece de uno a tres espacios, por lo general, basados en texto
- appCard(): Tarjeta de app que ofrece hasta cinco espacios, por lo general, basados en texto
- textDataCard(): Tarjeta de datos que ofrece hasta tres ranuras apiladas verticalmente, por lo general, basadas en texto o números
- iconDataCard(): Es una tarjeta de datos que ofrece hasta tres ranuras apiladas verticalmente, por lo general, basadas en texto o números, con un ícono.
- graphicDataCard(): Es una tarjeta de datos gráficos que ofrece un espacio para datos gráficos, como un indicador de progreso, y hasta dos espacios apilados verticalmente, por lo general, 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 distintas etapas.
Elementos de diseño de grupos
- buttonGroup(): Es un diseño de componente que ubica sus elementos secundarios en una secuencia horizontal.
- primaryLayout(): Es un diseño de pantalla completa que representa un estilo de 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.
Cómo aplicar un tema
En Material 3 Expressive, el sistema de colores 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 se deben crear dentro de él,
toman automáticamente los colores del esquema. Este enfoque permite que todos los elementos de la IU se adhieran automáticamente a los estándares de Material Design.
Para permitir que los usuarios elijan entre un esquema de colores que definas (como uno que refleje los colores de tu marca) y uno proporcionado por el sistema (ya sea derivado de la cara de reloj actual del usuario o uno elegido por el usuario), inicializa el MaterialScope de la siguiente manera:
val myColorScheme = ColorScheme( primary = Color.rgb(0, 0, 255).argb, // Blue onPrimary = Color.rgb(255, 255, 255).argb, // White // 27 more ) materialScope( context = context, deviceConfiguration = requestParams.deviceConfiguration, defaultColorScheme = myColorScheme ) { // If the user selects "no theme" in settings, myColorScheme is used. // Otherwise, the system-provided theme is used. }
Si eliges esta opción, proporciona un ícono de tarjeta monocromático para que se pueda teñir correctamente y obtener una visibilidad óptima en cualquier tema.
Para forzar que tus tarjetas aparezcan en el esquema de colores que proporciones, inhabilita la compatibilidad con los temas dinámicos configurando allowDynamicTheme como false:
materialScope( context = context, deviceConfiguration = requestParams.deviceConfiguration, 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 ColorScheme |
|---|---|
| containerColor | principal |
| 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 colores.
Es posible que debas desviarte de los tokens de color predeterminados para elementos específicos de la IU. Por ejemplo, es posible que quieras 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 estilos de botones estándar de Material 3 Expressive. Estas funciones crean instancias deButtonColorspreconfiguradas que asignan estilos comunes, como relleno, tonal o contorno, a los roles adecuados delColorSchemeactivo dentro deMaterialScope. 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
ButtonColorsque devuelven las funciones auxiliares 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 de forma explícita roles de color de reemplazo. Crea tu propio objeto
ButtonColorsy pásalo al componente. Para las tarjetas, usa el objetoCardColorsequivalente.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 (usa con precaución). Si bien, por lo 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, en especial si el tema cambia de forma dinámica.textEdgeButton( colors = filledButtonColors().copy( containerColor = android.graphics.Color.RED.argb, // Using named colors labelColor = 0xFFFFFF00.toInt().argb // Using a hex code for yellow ), // ... other parameters )
Tipografía
Para obtener más información sobre cómo usar la tipografía de manera eficaz en tus diseños, consulta la guía de diseño de tipografía.
Para crear coherencia visual en 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, por lo general, se usa 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 se adhiera a 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 los ejes de la fuente que no son el 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 en 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 construye 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 propiedad shape. Los valores provienen de la propiedad shapes de MaterialScope:
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:
private fun myImage(): LayoutElement = Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers( Modifiers.Builder() .setBackground(Background.Builder().setColor(argb(0xFFFF0000.toInt())).build()) .setPadding(ModifiersBuilders.Padding.Builder().setStart(dp(12f)).build()) .setSemantics(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:
private fun mySpannable(): LayoutElement = LayoutElementBuilders.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()
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():
- Proporciona un recurso de elementos de diseño con
setAndroidResourceByResId(). - Proporciona una imagen dinámica como un elemento
ByteArrayconsetInlineResource().
override fun onTileResourcesRequest( requestParams: ResourcesRequest ) = Futures.immediateFuture( Resources.Builder() .setVersion("1") .addIdToImageMapping( "image_from_resource", ResourceBuilders.ImageResource.Builder() .setAndroidResourceByResId( ResourceBuilders.AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.ic_walk) .build() ).build() ) .addIdToImageMapping( "image_inline", ResourceBuilders.ImageResource.Builder() .setInlineResource( ResourceBuilders.InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() )
Lista de tareas para 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 para relojes en 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 las 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. Usa 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 de acceso. La vista previa debe mostrar un estado "cargado" o "con acceso" 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 el tamaño de la pantalla, el idioma o la configuración regional del dispositivo. Esto es especialmente útil si la apariencia de tu tarjeta varía según el dispositivo.