Mostra aggiornamenti dinamici nei riquadri

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

Se utilizzi espressioni dinamiche, non devi aggiornare l'intero riquadro quando i suoi contenuti cambiano. Per creare un'esperienza più coinvolgente nelle tue schede, anima questi 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. Ecco alcuni esempi:

Per utilizzare un'espressione dinamica come possibile valore per un elemento nel riquadro, utilizza il *Proptipo di proprietà dinamica corrispondente dell'elemento e passa la fonte di dati al metodo setDynamicValue() della classe del generatore del tipo di proprietà dinamica.

I riquadri supportano i seguenti tipi di proprietà dinamiche:

Quando utilizzi un'espressione dinamica che influisce sulle dimensioni fisiche (qualsiasi valore in un riquadro, ad eccezione del colore), devi anche specificare un insieme di vincoli correlati, ad esempio un formato di stringa. Questi vincoli consentono al visualizzatore 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 expression dinamica, chiamando un metodo che inizia con setLayoutConstraintsForDynamic*.

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

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 in un singolo riquadro

Wear OS pone un limite al numero di espressioni che può avere un singolo riquadro. Se un riquadro contiene troppe espressioni dinamiche totali, i valori dinamici vengono ignorati e il sistema utilizza i valori statici che fornisci ai 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 poi trasmetti al riquadro per il rendering dei valori.

Per utilizzare le informazioni sullo stato nei riquadri:

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

    Kotlin

    companion object {
        val KEY_WATER_INTAKE = AppDataKey<DynamicInt32>("water_intake")
        val KEY_NOTE = AppDataKey<DynamicString>("note")
    }

    Java

    private static final AppDataKey<DynamicInt32> KEY_WATER_INTAKE =
        new AppDataKey<DynamicInt32>("water_intake");
    private static final AppDataKey<DynamicString> KEY_NOTE =
        new AppDataKey<DynamicString>("note");
  2. Nell'implementazione di onTileRequest(), chiama setState() e stabilisci mappature iniziali da ogni chiave a un determinato valore di dati dinamici:

    Kotlin

    override fun onTileRequest(requestParams: TileRequest):
            ListenableFuture<Tile> {
        val state = State.Builder()
            .addKeyToValueMapping(KEY_WATER_INTAKE,
                DynamicDataBuilders.DynamicDataValue.fromInt(200))
            .addKeyToValueMapping(KEY_NOTE,
                DynamicDataBuilders.DynamicDataValue.fromString("Note about day"))
        .build()
        // ...
    
        return Futures.immediateFuture(Tile.Builder()
            // Set resources, timeline, and other tile properties.
            .setState(state)
            .build()
        )

    Java

    @Override
    protected ListenableFuture<Tile> onTileRequest(
                ListenableFuture<Tile> {
        State state = new State.Builder()
            .addKeyToValueMapping(KEY_WATER_INTAKE,
                DynamicDataBuilders.DynamicDataValue.fromInt(200))
            .addKeyToValueMapping(KEY_NOTE,
                DynamicDataBuilders.DynamicDataValue.fromString("Note about day"))
        .build();
        // ...
    
        return Futures.immediateFuture(Tile.Builder()
            // Set resources, timeline, and other tile properties.
            .setState(state)
            .build()
        );
    }
  3. Quando crei il layout, utilizza un oggetto di tipo Dynamic* in un punto in cui vuoi mostrare questi dati dall'état. Puoi anche chiamare animate() per mostrare un'animazione dal valore precedente a quello corrente:

    Kotlin

    DynamicInt32.from(KEY_WATER_INTAKE).animate()

    Java

    DynamicInt32.from(KEY_WATER_INTAKE).animate();
  4. Se necessario, puoi anche aggiornare lo stato con nuovi valori. Può essere parte di LoadAction di una scheda.

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

    Kotlin

    val loadAction = LoadAction.Builder()
        .setRequestState(
            State.Builder()
                .addKeyToValueMapping(
                    KEY_WATER_INTAKE,
                    DynamicDataBuilders.DynamicDataValue.fromInt(400)
                )
                .build()
        )
        .build()

    Java

    LoadAction loadAction = new LoadAction.Builder()
        .setRequestState(
            new State.Builder()
                .addKeyToValueMapping(
                    KEY_WATER_INTAKE,
                    DynamicDataBuilders.DynamicDataValue.fromInt(400)
                ).build()
        ).build();