Cómo comenzar a usar tarjetas


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.Resources constan 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.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, como 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.
  • Mosaico: Es un objeto TileBuilders.Tile que 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): Tile de suspensión en lugar de usar ListenableFuture y anular onTileRequest().
  • MaterialScope preconfigurado: tileResponse() se ejecuta con MaterialScope como su receptor (configurado a través de parámetros del constructor, como allowDynamicTheme y defaultColorScheme), por lo que no necesitas unir tu diseño en una llamada redundante a materialScope().
  • Registro de recursos de llamada única: Incluye ProtoLayoutScope para 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 que Material3TileService controla los recursos automáticamente (final onTileResourcesRequest()), no anules onTileResourcesRequest().
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).

Una tarjeta de Wear OS creada con Material 3, que muestra el texto &quot;Hello World&quot;.
Figura 1. Mosaico "Hello World".

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:

  1. Inicia un alcance de Material Design: Llama a la función materialScope() y proporciona los valores context y deviceConfiguration obligatorios. Puedes incluir parámetros opcionales, como allowDynamicTheme y defaultColorScheme. allowDynamicTheme es true de forma predeterminada, y defaultColorScheme representa el ColorScheme que 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 cuando allowDynamicTheme es false). Cuando uses las APIs de ImageResource, como backgroundImage(), en un TileService personalizado, llama a materialScopeWithResources().

  2. 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() y textEdgeButton(), son funciones de extensión en MaterialScope 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(
                    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:

  1. El titleSlot, que suele usarse para un título o encabezado principal.
  2. mainSlot, para el contenido principal
  3. El bottomSlot, que suele usarse para acciones o información complementaria Aquí también aparece un botón de borde.
Diseño de tarjetas que muestra titleSlot, mainSlot y bottomSlot
Figura 2. titleSlot, mainSlot y bottomSlot.

El contenido de cada ranura es el siguiente:

  • titleSlot (opcional): Por lo general, son algunas palabras generadas por text().
  • 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, backgroundImage como 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

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.

El sistema de colores de Material 3 Expressive, que muestra los roles de color organizados en grupos, como primario, secundario, terciario, error, superficie y contorno.
Figura 3: El sistema de colores de Material 3 Expressive.

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:

  1. 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 de ButtonColors preconfiguradas que asignan estilos comunes, como relleno, tonal o contorno, a los roles adecuados del ColorScheme activo dentro de MaterialScope. 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 devuelven las funciones auxiliares con su método copy() si solo necesitas cambiar uno o dos tokens:

    textEdgeButton(
        colors =
        filledButtonColors()
            .copy(
                containerColor = colorScheme.tertiary,
                labelColor = colorScheme.onTertiary
            ),
        // ... other parameters
    )

  2. Proporciona de forma explícita roles de color de reemplazo. Crea tu propio objeto ButtonColors y pásalo al componente. Para las tarjetas, usa el objeto CardColors equivalente.

    textEdgeButton(
        colors =
        ButtonColors(
            // the materialScope makes colorScheme available
            containerColor = colorScheme.secondary,
            iconColor = colorScheme.secondaryDim,
            labelColor = colorScheme.onSecondary,
            secondaryLabelColor = colorScheme.onSecondary
        ),
        // ... other parameters
    )

  3. 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():

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.