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.
Utilizzando le espressioni dinamiche, non devi aggiornare l'intero riquadro quando i contenuti cambiano. Per creare un'esperienza più coinvolgente nei 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. Ecco alcuni esempi:
- Diversi valori di lunghezza, inclusa la lunghezza di un
Arcoggetto e la lunghezza di unCircularProgressIndicatoroggetto. - Qualsiasi colore, ad esempio il colore dei contenuti di un oggetto
Button. - Molti valori di stringa, inclusi i contenuti di un oggetto
Text, i contenuti di un oggettoLayoutElementsBuilders.Texte la descrizione dei contenuti di un oggettoCircularProgressIndicator.
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:
- Per le dimensioni lineari, misurate in pixel indipendenti dalla visualizzazione, utilizza
DimensionBuilders.DpProp. - Per le dimensioni angolari, misurate in gradi, utilizza
DimensionBuilders.DegreesProp. - Per i valori di stringa, utilizza
TypeBuilders.StringProp. - Per i valori di colore, utilizza
ColorBuilders.ColorProp. - Per i valori in virgola mobile, utilizza
TypeBuilders.FloatProp.
Quando utilizzi un'espressione dinamica che influisce sulle dimensioni fisiche, ovvero qualsiasi valore in un riquadro tranne il colore, devi anche specificare un insieme di vincoli correlati, ad esempio un formato di 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, questi vincoli vengono specificati 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 3 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() )
Utilizzare un numero ridotto di espressioni in 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 torna ai valori statici forniti ai rispettivi tipi di proprietà dinamiche.
Consolidare i dati dinamici in un oggetto di stato
Puoi consolidare l'ultimo set di aggiornamenti dalle origini dati in uno stato, che passi al riquadro per il rendering dei valori.
Per utilizzare le informazioni sullo stato nei riquadri, completa questi passaggi:
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") }
Nell'implementazione di
onTileRequest(), chiamasetState()e stabilisci i mapping iniziali da ogni chiave a un valore di dati dinamici specifico: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() ) }
Quando crei il layout, in un punto in cui vuoi mostrare questi dati dallo stato, utilizza un oggetto di tipo
Dynamic*. Puoi anche chiamareanimate()per mostrare un'animazione dal valore precedente al valore corrente:val waterIntakeValue = DynamicBuilders.DynamicInt32.from(KEY_WATER_INTAKE)
Se necessario, puoi anche aggiornare lo stato con nuovi valori. Questo può far parte di un riquadro
LoadAction.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" ) )
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Eseguire la migrazione agli spazi dei nomi ProtoLayout
- Guida introduttiva ai riquadri
- Altre considerazioni