Inizia a utilizzare i riquadri


Per iniziare a fornire riquadri dalla tua app, includi le seguenti dipendenze nel file build.gradle della tua app.

Alla moda

dependencies {
    // Use to implement support for wear tiles
    implementation "androidx.wear.tiles:tiles:1.4.1"

    // Use to utilize standard components and layouts in your tiles
    implementation "androidx.wear.protolayout:protolayout:1.2.1"

    // Use to utilize components and layouts with Material Design in your tiles
    implementation "androidx.wear.protolayout:protolayout-material:1.2.1"

    // Use to include dynamic expressions in your tiles
    implementation "androidx.wear.protolayout:protolayout-expression:1.2.1"

    // Use to preview wear tiles in your own app
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.4.1"

    // Use to fetch tiles from a tile provider in your tests
    testImplementation "androidx.wear.tiles:tiles-testing:1.4.1"
}

Kotlin

dependencies {
    // Use to implement support for wear tiles
    implementation("androidx.wear.tiles:tiles:1.4.1")

    // Use to utilize standard components and layouts in your tiles
    implementation("androidx.wear.protolayout:protolayout:1.2.1")

    // Use to utilize components and layouts with Material Design in your tiles
    implementation("androidx.wear.protolayout:protolayout-material:1.2.1")

    // Use to include dynamic expressions in your tiles
    implementation("androidx.wear.protolayout:protolayout-expression:1.2.1")

    // Use to preview wear tiles in your own app
    debugImplementation("androidx.wear.tiles:tiles-renderer:1.4.1")

    // Use to fetch tiles from a tile provider in your tests
    testImplementation("androidx.wear.tiles:tiles-testing:1.4.1")
}

Concetti principali

Le schede non sono create nello stesso modo delle app per Android e utilizzano diversi concetti:

  • Modelli di layout:definiscono la disposizione complessiva degli elementi visivi sul display. Questo viene ottenuto tramite la funzione primaryLayout().
  • Elementi di layout:rappresentano un singolo elemento grafico, ad esempio un pulsante o una scheda, oppure più elementi raggruppati utilizzando una colonna, un buttonGroup o un elemento simile. Questi elementi sono incorporati in un modello di layout.
  • Risorse: gli oggetti ResourceBuilders.Resources sono costituiti da una mappa di coppie chiave-valore delle risorse Android (immagini) necessarie per eseguire il rendering di un layout e da una versione.
  • Sequenza temporale:un oggetto TimelineBuilders.Timeline è un elenco di una o più istanze di un oggetto layout. Puoi fornire vari meccanismi ed espressioni per indicare quando il visualizzatore deve passare da un oggetto layout a un altro, ad esempio per interrompere la visualizzazione di un layout in un momento specifico.
  • Stato: una struttura di dati di tipo StateBuilders.State che viene passata tra riquadro e app per consentire ai due componenti di comunicare tra loro. Ad esempio, se viene toccato un pulsante nel riquadro, lo stato contiene l'ID del pulsante. Puoi anche scambiare i tipi di dati utilizzando una mappa.
  • Riquadro:un oggetto TileBuilders.Tile che rappresenta un riquadro, costituito da una sequenza temporale, un ID versione delle risorse, un intervallo di aggiornamento e uno stato.
  • Protolayout: questo termine compare nel nome di varie classi relative ai riquadri e si riferisce alla libreria Protolayout per Wear OS, una libreria di grafica utilizzata su varie piattaforme Wear OS.

Creare un riquadro

Per fornire un riquadro dalla tua app, implementa un servizio di tipo TileService e registralo nel file manifest. Da qui, il sistema richiede i riquadri necessari durante le chiamate a onTileRequest() e le risorse durante le chiamate 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()
        )
}

Aggiungi un servizio all'interno del tag <application> del file 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>

Il filtro delle autorizzazioni e delle intenzioni registra questo servizio come fornitore di riquadri.

Le risorse icona, etichetta, descrizione e anteprima vengono mostrate all'utente quando configura i riquadri sullo smartphone o sullo smartwatch. Tieni presente che la risorsa di anteprima supporta tutti i qualificatori delle risorse standard di Android, quindi è possibile variare l'anteprima in base a fattori come le dimensioni dello schermo e la lingua del dispositivo. Per altri consigli, consulta la lista di controllo di anteprima.

Esegui il deployment dell'app e aggiungi il riquadro al carosello di riquadri (esiste anche un modo più adatto agli sviluppatori per visualizzare l'anteprima di un riquadro, ma per il momento esegui l'operazione manualmente).

Riquadro &quot;Hello World&quot;.
Figura 1. Riquadro "Hello World".

Per un esempio completo, consulta il codice di esempio su GitHub o il codelab.

Creare l'interfaccia utente per le riquadri

Gli elementi dell'interfaccia utente espressiva di Material 3 vengono creati utilizzando un approccio strutturato basato sul pattern di builder sicuro per i tipi di Kotlin.

Layout

Per creare il layout:

  1. Avvia un ambito Material Design: chiama la funzione materialScope(), fornendo context e deviceConfiguration richiesti. Puoi includere parametri facoltativi, come allowDynamicTheme e defaultColorScheme. Per impostazione predefinita, allowDynamicTheme è true e defaultColorScheme rappresenta il ColorScheme utilizzato quando i colori dinamici non sono disponibili, ad esempio quando l'utente ha disattivato la funzionalità, o quando non è supportata dal dispositivo o allowDynamicTheme è false.

  2. Crea l'interfaccia utente nell'ambito: tutti i componenti dell'interfaccia utente per un determinato layout dei riquadri devono essere definiti all'interno della funzione lambda di una singola chiamata di materialScope() di primo livello. Queste funzioni di componenti, come primaryLayout() e textEdgeButton(), sono funzioni di estensione di MaterialScope e sono disponibili solo quando vengono chiamate in questo ambito del ricevitore.

    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) }
        )
    }
    

Slot machine

In M3, il layout delle schede utilizza un approccio ispirato a Compose che sfrutta tre slot distinti. Dall'alto verso il basso, sono:

  1. titleSlot, in genere per un titolo o un'intestazione principale.
  2. mainSlot, per i contenuti principali.
  3. bottomSlot, spesso utilizzato per azioni o informazioni supplementari. Qui viene visualizzato anche un pulsante laterale.
Layout dei riquadri che mostra titleSlot, mainSlot e bottomSlot
Figura 2. titleSlot, mainSlot e bottomSlot.

I contenuti di ogni spazio sono i seguenti:

  • titleSlot (facoltativo): in genere alcune parole generate da text().
  • mainSlot (obbligatorio): componenti organizzati in strutture come righe, colonne e gruppi di pulsanti. Questi componenti possono anche essere incorporati in modo ricorsivo l'uno nell'altro; ad esempio, una colonna può contenere righe.
  • bottomSlot (facoltativo): in genere viene inserito un pulsante adiacente al bordo o un'etichetta di testo.

Poiché non è possibile scorrere i riquadri, non sono disponibili componenti per la visualizzazione di pagine, lo scorrimento o la gestione di elenchi di contenuti lunghi. Assicurati che i contenuti rimangano visibili quando le dimensioni dei caratteri aumentano o il testo diventa più lungo a causa della traduzione.

Componenti dell'interfaccia utente

La libreria protolayout-material3 fornisce un numero elevato di componenti progettati in base alle specifiche di Material 3 Expressive e ai consigli per l'interfaccia utente.

Pulsanti

  • textButton(): pulsante con un singolo slot per contenuti di testo (brevi)
  • iconButton(): pulsante con un singolo slot per rappresentare un'icona
  • avatarButton(): pulsante avatar a forma di pillola che offre fino a tre scomparti per inserire contenuti che rappresentano un'etichetta e un'etichetta secondaria impilate verticalmente e un'immagine (avatar) accanto
  • imageButton(): pulsante immagine selezionabile che non offre altri scomparti, solo immagine (ad esempio backgroundImage come sfondo)
  • compactButton(): pulsante compatto che offre fino a due slot per inserire contenuti impilzati orizzontalmente che rappresentano un'icona e un testo accanto
  • button(): pulsante a forma di pillola che offre fino a tre spazi per inserire contenuti che rappresentano un'etichetta e un'etichetta secondaria impilate verticalmente e un'icona accanto

Pulsanti laterali

  • iconEdgeButton(): pulsante laterale che offre un singolo slot per inserire un'icona o contenuti piccoli e rotondi simili
  • textEdgeButton(): pulsante laterale che offre un singolo spazio per inserire un testo o contenuti di dimensioni simili

Carte

  • titleCard(): scheda del titolo che offre da uno a tre spazi, solitamente basati su testo
  • appCard(): scheda dell'app che offre fino a cinque slot, in genere basati su testo
  • textDataCard(): scheda di dati che offre fino a tre slot impilati verticalmente, in genere basati su testo o numeri
  • iconDataCard(): scheda di dati che offre fino a tre slot impilati verticalmente, in genere basati su testo o numeri, con un'icona
  • graphicDataCard(): scheda di dati grafici che offre uno slot per i dati grafici, ad esempio l'indicatore di avanzamento, e fino a due slot impilati verticalmente, solitamente per le descrizioni di testo

Indicatori di avanzamento

Raggruppare elementi di layout

  • buttonGroup(): componente di layout che inserisce gli elementi secondari in una sequenza orizzontale
  • primaryLayout(): layout a schermo intero che rappresenta uno stile di layout M3 suggerito, responsive e che si occupa del posizionamento degli elementi, insieme ai margini e ai padding consigliati applicati

Applicazione tema

In Material 3 Expressive, il sistema di colori è definito da 29 ruoli di colore standard, organizzati in sei gruppi: primario, secondario, terziario, errore, superficie e contorni.

Sistema di colori espressivi di Material 3
Figura 3. Il sistema di colori espressivi di Material 3.

Un ColorScheme mappa ciascuno di questi 29 ruoli a un colore corrispondente e, poiché fa parte del MaterialScope e i componenti devono essere creati al suo interno, acquisiscono automaticamente i colori dallo schema. Questo approccio consente a tutti gli elementi dell'interfaccia utente di rispettare automaticamente gli standard di Material Design.

Per consentire agli utenti di scegliere tra una combinazione di colori definita da te, ad esempio una che rispecchi i colori del tuo brand, e una fornita dal sistema, ricavata dal quadrante corrente dell'utente o scelta dall'utente, inizializza MaterialScope come segue:

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.
}

Per forzare la visualizzazione dei riquadri nella combinazione di colori che fornisci, disattiva il supporto per i temi dinamici impostando allowDynamicTheme su false:

materialScope(
  allowDynamicTheme = false,
  defaultColorScheme = myColorScheme
) {
  // myColorScheme is *always* used.
}

Colore

Ogni singolo componente utilizza un sottoinsieme dei 29 ruoli di colore definiti da un ColorScheme. Ad esempio, i pulsanti utilizzano fino a quattro colori, che per impostazione predefinita vengono ricavati dal gruppo "principale" del ColorScheme attivo:

Token del componente ButtonColors Ruolo ColorScheme
containerColor principale
iconColor onPrimary
labelColor onPrimary
secondaryLabelColor onPrimary (opacità 0,8)

Potresti dover discostarti dai token di colore predefiniti per elementi specifici dell'interfaccia utente. Ad esempio, potresti voler utilizzare un textEdgeButton con colori del gruppo "secondario" o "terziario" anziché "principale" per risaltare e ottenere un contrasto migliore.

Puoi personalizzare i colori dei componenti in diversi modi:

  1. Utilizza una funzione di supporto per i colori predefiniti. Utilizza funzioni di supporto come filledTonalButtonColors() per applicare gli stili dei pulsanti standard per Material 3 Expressive. Queste funzioni creano istanze preconfigurate di ButtonColors che mappano stili comuni come riempiti, a tonalità o con contorni ai ruoli appropriati dell'ColorScheme attivo all'interno del MaterialScope. In questo modo, puoi applicare stili coerenti senza dover definire manualmente ogni colore per i tipi di pulsanti comuni.

    textEdgeButton(
        colors = filledButtonColors() // default
        /* OR colors = filledTonalButtonColors() */
        /* OR colors = filledVariantButtonColors() */
        // ... other parameters
    )
    

    Per le schede, utilizza la famiglia di funzioni filledCardColors() equivalente.

    Puoi anche modificare l'oggetto ButtonColors restituito dalle funzioni di supporto utilizzando il relativo metodo copy() se devi modificare solo uno o due token:

    textEdgeButton(
        colors =
            filledButtonColors()
                .copy(
                    containerColor = colorScheme.tertiary,
                    labelColor = colorScheme.onTertiary
                )
        // ... other parameters
    )
    
  2. Fornisci esplicitamente i ruoli di colore sostitutivi. Crea il tuo oggetto ButtonColors e passalo al componente. Per le carte, utilizza l'oggetto 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. Specifica colori fissi (da usare con cautela). Sebbene in genere sia consigliato specificare i colori in base al loro ruolo semantico (ad es. colorScheme.primary), puoi anche fornire valori di colore diretti. Questo approccio deve essere utilizzato con parsimonia, in quanto può portare a incoerenze con il tema generale, soprattutto se il tema cambia in modo dinamico.

    textEdgeButton(
        colors = filledButtonColors().copy(
            containerColor = android.graphics.Color.RED.argb, // Using named colors
            labelColor = 0xFFFFFF00.argb // Using a hex code for yellow
        )
        // ... other parameters
    )
    

Tipografia

Per creare coerenza visiva sulla piattaforma Wear OS e ottimizzare il rendimento, tutto il testo dei riquadri viene visualizzato utilizzando un carattere fornito dal sistema. ovvero i riquadri non supportano i caratteri personalizzati. Su Wear OS 6 e versioni successive, si tratta di un carattere specifico dell'OEM. Nella maggior parte dei casi si tratta di un carattere variabile, che offre un'esperienza più espressiva e un controllo più granulare.

Per creare uno stile di testo, in genere si utilizza il metodo text() insieme alle costanti tipografiche. Questo componente ti consente di utilizzare i ruoli di tipografia predefiniti in Material 3 Expressive, che aiutano la tua scheda a rispettare le best practice di tipografia consolidate per leggibilità e gerarchia. La libreria offre un insieme di 18 costanti di tipografia semantica, come BODY_MEDIUM. Queste costanti influiscono anche sugli assi dei caratteri diversi dalle dimensioni.

text(
    text = "Hello, World!".layoutString,
    typography = BODY_MEDIUM,
)

Per un maggiore controllo, puoi fornire impostazioni aggiuntive. Su Wear OS 6 e versioni successive, è probabile che venga utilizzato un carattere variabile, che puoi modificare lungo gli assi italico, peso, larghezza e rotondità. Puoi controllare questi assi utilizzando il parametro 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)),
)

Infine, se devi controllare le dimensioni o la spaziatura delle lettere (non consigliato), utilizza basicText() anziché text() e crea un valore per la proprietà fontStyle utilizzando fontStyle().

Forma e margini

Puoi modificare il raggio di curvatura degli angoli di quasi tutti i componenti utilizzando la relativa proprietàshape. I valori provengono dalla proprietà MaterialScope shapes:

textButton(
   height = expand(),
   width = expand(),
   shape = shapes.medium, // OR another value like shapes.full
   colors = filledVariantButtonColors(),
   labelContent = { text("Hello, World!".layoutString) },
)

Dopo aver modificato la forma di un componente, se ritieni che lasci troppo o troppo poco spazio attorno al bordo del display, regola i margini utilizzando il parametro margin di primaryLayout():

primaryLayout(
    mainSlot = {
        textButton(
            shape = shapes.small,
            /* ... */
        )
    },
    // margin constants defined in androidx.wear.protolayout.material3.PrimaryLayoutMargins
    margins = MAX_PRIMARY_LAYOUT_MARGIN,
)

Archi

Sono supportati i seguenti elementi contenitore secondari Arc:

  • ArcLine: mostra una linea curva attorno all'arco.
  • ArcText: consente di visualizzare il testo curvo nell'arco.
  • ArcAdapter: mostra un elemento di layout di base nell'arco, disegnato in corrispondenza di una tangente all'arco.

Per ulteriori informazioni, consulta la documentazione di riferimento per ciascuno dei tipi di elementi.

Modificatori

A ogni elemento di layout disponibile è possibile applicare facoltativamente dei modificatori. Utilizza questi modificatori per le seguenti finalità:

  • Modificare l'aspetto visivo del layout. Ad esempio, aggiungi uno sfondo, un bordino o un'area di a capo all'elemento di layout.
  • Aggiungi metadati sul layout. Ad esempio, aggiungi un modificatore di semantica all'elemento di layout per l'utilizzo con gli screen reader.
  • Aggiungi funzionalità. Ad esempio, aggiungi un modificatore selezionabile all'elemento di layout per rendere interattivo il riquadro. Per ulteriori informazioni, consulta Interagire con i riquadri.

Ad esempio, possiamo personalizzare l'aspetto e i metadati predefiniti di un Image, come mostrato nell'esempio di codice seguente:

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();
}

Espandibili

Un Spannable è un tipo speciale di contenitore che dispone gli elementi in modo simile al testo. Questa operazione è utile quando vuoi applicare uno stile diverso a una sola substringa in un blocco di testo più grande, cosa non possibile con l'elemento Text.

Un contenitore Spannable è riempito con Span elementi secondari. Non sono consentiti altri elementi secondari o istanze Spannable nidificate.

Esistono due tipi di elementi Span figlio:

  • SpanText: consente di visualizzare il testo con uno stile specifico.
  • SpanImage: consente di visualizzare un'immagine in linea con il testo.

Ad esempio, puoi mettere in corsivo la parola "world" in un riquadro "Hello world" e inserire un'immagine tra le parole, come mostrato nel seguente esempio di codice:

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();
}

Lavorare con le risorse

Le schede non hanno accesso alle risorse della tua app. Ciò significa che non puoi passare un ID immagine Android a un elemento di layout Image e aspettarti che venga risolto. Sostituisci il metodo onTileResourcesRequest() e fornisci le risorse manualmente.

Esistono due modi per fornire immagini all'interno del metodo onTileResourcesRequest():

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()
);
}

Elenco di controllo delle immagini di anteprima dei riquadri

Il sistema mostra l'immagine di anteprima del riquadro, a cui si fa riferimento nel file manifest dell'app Android, nell'editor del carosello di riquadri. Questo editor viene visualizzato sia sui dispositivi Wear OS sia nell'app complementare dello smartwatch sugli smartphone.

Per aiutare gli utenti a sfruttare al meglio questa immagine di anteprima, verifica i seguenti dettagli del riquadro:

  • Riflette il design più recente. L'anteprima deve rappresentare con precisione il design più recente della tua scheda.
  • Utilizza un tema di colore statico. Utilizza il tema a colori statico della scheda, non uno dinamico.
  • Include l'icona dell'app. Verifica che l'icona dell'app venga visualizzata nella parte superiore dell'immagine di anteprima.
  • Mostra lo stato caricato/di accesso. L'anteprima deve mostrare uno stato "caricato" o "accesso eseguito" completamente funzionale, evitando contenuti vuoti o segnaposto.
  • (Facoltativo) Utilizza le regole di risoluzione delle risorse per la personalizzazione. Valuta la possibilità di utilizzare le regole di risoluzione delle risorse di Android per fornire anteprime che corrispondano alle impostazioni di lingua, dimensioni del display o impostazioni internazionali del dispositivo. Questo è particolarmente utile se l'aspetto del riquadro varia da un dispositivo all'altro.