Mostra aggiornamenti dinamici nei riquadri

A partire da Riquadri 1.2, puoi trasmettere in streaming gli aggiornamenti dei dati della piattaforma utilizzando le espressioni dinamiche. Puoi quindi associare questi aggiornamenti alle animazioni nei tuoi riquadri. La tua app riceve aggiornamenti di questo valore ogni secondo.

Utilizzando le espressioni dinamiche, non è necessario aggiornare l'intero riquadro quando il relativo contenuto cambia. Per creare un'esperienza più coinvolgente nei tuoi riquadri, anima gli oggetti dinamici.

Associare espressioni dinamiche alle origini dati

Gli spazi dei nomi androidx.wear.protolayout e androidx.wear.protolayout.material contengono molte classi i cui campi accettano espressioni dinamiche. Alcuni esempi sono:

Per utilizzare un'espressione dinamica come valore possibile per un elemento nel riquadro, utilizza il tipo di proprietà dinamica *Prop corrispondente dell'elemento e trasmetti l'origine dati al metodo setDynamicValue() della classe del builder del tipo di proprietà dinamica.

I riquadri supportano i seguenti tipi di proprietà dinamiche:

Quando utilizzi un'espressione dinamica che influisce sulle dimensioni fisiche, ovvero qualsiasi valore in un riquadro, ad eccezione del colore, devi anche specificare un insieme di vincoli correlati, ad esempio un formato stringa. Questi vincoli consentono al renderer di sistema di determinare la quantità massima di spazio che un valore può occupare all'interno del riquadro. In genere, specifichi questi vincoli a livello di elemento, non a livello di espressione dinamica, chiamando un metodo che inizia con setLayoutConstraintsForDynamic*.

Il seguente snippet di codice mostra come visualizzare gli aggiornamenti della frequenza cardiaca utilizzando tre cifre, con un valore di riserva di --:

override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
    Futures.immediateFuture(
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
            .setTileTimeline(
                Timeline.fromLayoutElement(
                    Text.Builder(
                        this,
                        TypeBuilders.StringProp.Builder("--")
                            .setDynamicValue(
                                PlatformHealthSources.heartRateBpm()
                                    .format()
                                    .concat(DynamicBuilders.DynamicString.constant(" bpm"))
                            )
                            .build(),
                        TypeBuilders.StringLayoutConstraint.Builder("000").build(),
                    )
                        .build()
                )
            )
            .build()
    )

Utilizza un numero ridotto di espressioni all'interno di un singolo riquadro

Wear OS impone un limite al numero di espressioni che un singolo riquadro può avere. Se un riquadro contiene troppe espressioni dinamiche totali, i valori dinamici vengono ignorati e il sistema ripristina i valori statici forniti per i rispettivi tipi di proprietà dinamiche.

Consolidare i dati dinamici in un oggetto stato

Puoi consolidare l'ultimo insieme di aggiornamenti delle origini dati in uno stato, che trasferisci al riquadro per il rendering dei valori.

Per utilizzare le informazioni sullo stato nei riquadri, completa questi passaggi:

  1. Stabilisci un insieme di chiavi che rappresentano i diversi valori dello stato del riquadro. Questo esempio crea chiavi per l'assunzione di acqua e una nota qqq:

    companion object {
        val KEY_WATER_INTAKE = intAppDataKey("key_water_intake")
        val KEY_NOTE = stringAppDataKey("key_note")
    }

  2. Nell'implementazione di onTileRequest(), chiama setState() e stabilisci le mappature iniziali da ogni chiave a un particolare valore di dati dinamici:

    override fun onTileRequest(
        requestParams: RequestBuilders.TileRequest
    ): ListenableFuture<Tile?> {
        // If the tile hasn't had any state set yet, use the default values
        val state =
            if (requestParams.currentState.keyToValueMapping.isNotEmpty())
                requestParams.currentState
            else
                StateBuilders.State.Builder()
                    .setStateMap(
                        dynamicDataMapOf(
                            KEY_WATER_INTAKE mapTo 200,
                            KEY_NOTE mapTo "Good"
                        )
                    )
                    .build()
    
        return Futures.immediateFuture(
            Tile.Builder()
                // Set resources, timeline, and other tile properties.
                .setState(state)
                .build()
        )
    }

  3. Quando crei il layout, in un punto in cui vuoi mostrare questi dati dallo stato, utilizza un oggetto di tipo Dynamic*. Puoi anche chiamare animate() per mostrare un'animazione dal valore precedente a quello attuale:

    val waterIntakeValue =
        DynamicBuilders.DynamicInt32.from(KEY_WATER_INTAKE)

  4. Se necessario, puoi anche aggiornare lo stato con nuovi valori. Può far parte del LoadAction di un riquadro.

    In questo esempio, il valore di assunzione di acqua viene aggiornato a 400:

    val loadAction =
        loadAction(
            dynamicDataMapOf(
                KEY_WATER_INTAKE mapTo 400,
                KEY_NOTE mapTo "Outstanding"
            )
        )