Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
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:
Per le dimensioni lineari, misurate in pixel indipendenti dal display, utilizza
DimensionBuilders.DpProp.
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 --:
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:
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:
Nell'implementazione di onTileRequest(), chiama setState() e stabilisci mappature iniziali da ogni chiave a un determinato valore di dati dinamici:
Kotlin
overridefunonTileRequest(requestParams:TileRequest):ListenableFuture<Tile>{valstate=State.Builder().addKeyToValueMapping(KEY_WATER_INTAKE,DynamicDataBuilders.DynamicDataValue.fromInt(200)).addKeyToValueMapping(KEY_NOTE,DynamicDataBuilders.DynamicDataValue.fromString("Note about day")).build()// ...returnFutures.immediateFuture(Tile.Builder()// Set resources, timeline, and other tile properties..setState(state).build())
Java
@OverrideprotectedListenableFuture<Tile>onTileRequest(ListenableFuture<Tile>{Statestate=newState.Builder().addKeyToValueMapping(KEY_WATER_INTAKE,DynamicDataBuilders.DynamicDataValue.fromInt(200)).addKeyToValueMapping(KEY_NOTE,DynamicDataBuilders.DynamicDataValue.fromString("Note about day")).build();// ...returnFutures.immediateFuture(Tile.Builder()// Set resources, timeline, and other tile properties..setState(state).build());}
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();
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:
I campioni di contenuti e codice in questa pagina sono soggetti alle licenze descritte nella Licenza per i contenuti. Java e OpenJDK sono marchi o marchi registrati di Oracle e/o delle sue società consociate.
Ultimo aggiornamento 2025-08-30 UTC.
[[["Facile da capire","easyToUnderstand","thumb-up"],["Il problema è stato risolto","solvedMyProblem","thumb-up"],["Altra","otherUp","thumb-up"]],[["Mancano le informazioni di cui ho bisogno","missingTheInformationINeed","thumb-down"],["Troppo complicato/troppi passaggi","tooComplicatedTooManySteps","thumb-down"],["Obsoleti","outOfDate","thumb-down"],["Problema di traduzione","translationIssue","thumb-down"],["Problema relativo a esempi/codice","samplesCodeIssue","thumb-down"],["Altra","otherDown","thumb-down"]],["Ultimo aggiornamento 2025-08-30 UTC."],[],[],null,["Starting in Tiles 1.2, you can stream platform data updates using\n[dynamic expressions](/training/wearables/data/dynamic). You can then associate these updates with animations\nin your tiles. Your app gets updates to this value every second.\n\nUsing dynamic expressions, you don't need to refresh the entire tile when its\ncontent changes. To create a more engaging experience in your tiles, animate\nthose dynamic objects.\n\nAssociate dynamic expressions with data sources\n\nThe `androidx.wear.protolayout` and `androidx.wear.protolayout.material`\nnamespaces contain many classes whose fields accept dynamic expressions.\nSeveral examples include the following:\n\n- Several length values, including the [length of an `Arc` object](/reference/androidx/wear/protolayout/LayoutElementBuilders.ArcLine#getLength()) and the [length of a `CircularProgressIndicator`](/reference/androidx/wear/protolayout/material/CircularProgressIndicator#getProgress()) object.\n- Any color, such as the [content color of a `Button` object](/reference/androidx/wear/protolayout/material/ButtonColors#getContentColor()).\n- Many string values, including the [content of a `Text` object](/reference/androidx/wear/protolayout/material/Text#getText()), the [content of a `LayoutElementsBuilders.Text` object](/reference/androidx/wear/protolayout/LayoutElementBuilders.Text#getText()), and the [content\n description of a `CircularProgressIndicator` object](/reference/androidx/wear/protolayout/material/CircularProgressIndicator#getContentDescription()).\n\nTo use a dynamic expression as a possible value for an element in your tile, use\nthe element's corresponding `*Prop` dynamic property type and pass in the data\nsource to the dynamic property type's builder class's `setDynamicValue()`\nmethod.\n\nTiles support these dynamic property types:\n\n- For linear dimensions, measured in display-independent pixels, use [`DimensionBuilders.DpProp`](/reference/androidx/wear/tiles/DimensionBuilders.DpProp).\n- For angular dimensions, measured in degrees, use [`DimensionBuilders.DegreesProp`](/reference/androidx/wear/tiles/DimensionBuilders.DegreesProp).\n- For string values, use [`TypeBuilders.StringProp`](/reference/androidx/wear/protolayout/TypeBuilders.StringProp).\n- For color values, use [`ColorBuilders.ColorProp`](/reference/androidx/wear/protolayout/ColorBuilders.ColorProp).\n- For floating-point values, use [`TypeBuilders.FloatProp`](/reference/androidx/wear/protolayout/TypeBuilders.FloatProp).\n\nWhen you use a dynamic expression that affects physical dimensions---any value in\na tile except for color---you must also specify a set of related constraints, such\nas a string format. These constraints allow the system renderer to determine the\nmaximum amount of space that a value could occupy within your tile. Usually, you\nspecify these constraints at the element level, not at the dynamic expression\nlevel, by calling a method that starts with `setLayoutConstraintsForDynamic*`.\n| **Note:** The Material components set these layout constraints automatically.\n\nThe following code snippet shows how to display updates to a heart rate using 3\ndigits, with a fallback value of `--`: \n\n```kotlin\noverride fun onTileRequest(requestParams: RequestBuilders.TileRequest) =\n Futures.immediateFuture(\n Tile.Builder()\n .setResourcesVersion(RESOURCES_VERSION)\n .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes\n .setTileTimeline(\n Timeline.fromLayoutElement(\n Text.Builder(\n this,\n TypeBuilders.StringProp.Builder(\"--\")\n .setDynamicValue(\n PlatformHealthSources.heartRateBpm()\n .format()\n .concat(DynamicBuilders.DynamicString.constant(\" bpm\"))\n )\n .build(),\n TypeBuilders.StringLayoutConstraint.Builder(\"000\").build(),\n )\n .build()\n )\n )\n .build()\n )https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/wear/src/main/java/com/example/wear/snippets/tile/Tile.kt#L178-L200\n```\n\nUse a small number of expressions within a single tile\n\nWear OS [places a limit](/training/wearables/data/dynamic#use-limited-number-per-screen) on the number of expressions that a single tile can\nhave. If a tile contains too many total dynamic expressions, dynamic values are\nignored, and the system falls back to the static values that you provide to the\nrespective dynamic property types.\n\nConsolidate dynamic data into a state object\n\nYou can consolidate the latest set of updates from data sources into a *state*,\nwhich you pass over to your tile for value rendering.\n\nTo use state information in your tiles, complete these steps:\n\n1. Establish a set of keys that represent the different values of your tile's\n state. This example creates keys for water intake and a note:\n\n Kotlin \n\n ```kotlin\n companion object {\n val KEY_WATER_INTAKE = AppDataKey\u003cDynamicInt32\u003e(\"water_intake\")\n val KEY_NOTE = AppDataKey\u003cDynamicString\u003e(\"note\")\n }\n ```\n\n Java \n\n ```java\n private static final AppDataKey\u003cDynamicInt32\u003e KEY_WATER_INTAKE =\n new AppDataKey\u003cDynamicInt32\u003e(\"water_intake\");\n private static final AppDataKey\u003cDynamicString\u003e KEY_NOTE =\n new AppDataKey\u003cDynamicString\u003e(\"note\");\n ```\n2. In your implementation of `onTileRequest()`, call `setState()` and establish\n initial mappings from each key to a particular dynamic data value:\n\n Kotlin \n\n ```kotlin\n override fun onTileRequest(requestParams: TileRequest):\n ListenableFuture\u003cTile\u003e {\n val state = State.Builder()\n .addKeyToValueMapping(KEY_WATER_INTAKE,\n DynamicDataBuilders.DynamicDataValue.fromInt(200))\n .addKeyToValueMapping(KEY_NOTE,\n DynamicDataBuilders.DynamicDataValue.fromString(\"Note about day\"))\n .build()\n // ...\n\n return Futures.immediateFuture(Tile.Builder()\n // Set resources, timeline, and other tile properties.\n .setState(state)\n .build()\n )\n ```\n\n Java \n\n ```java\n @Override\n protected ListenableFuture\u003cTile\u003e onTileRequest(\n ListenableFuture\u003cTile\u003e {\n State state = new State.Builder()\n .addKeyToValueMapping(KEY_WATER_INTAKE,\n DynamicDataBuilders.DynamicDataValue.fromInt(200))\n .addKeyToValueMapping(KEY_NOTE,\n DynamicDataBuilders.DynamicDataValue.fromString(\"Note about day\"))\n .build();\n // ...\n\n return Futures.immediateFuture(Tile.Builder()\n // Set resources, timeline, and other tile properties.\n .setState(state)\n .build()\n );\n }\n ```\n3. When you create your layout, in a place where you want to show this data\n from state, use a `Dynamic*` type object. You can also call `animate()` to\n show an animation from the previous value to the current value:\n\n Kotlin \n\n ```kotlin\n DynamicInt32.from(KEY_WATER_INTAKE).animate()\n ```\n\n Java \n\n ```java\n DynamicInt32.from(KEY_WATER_INTAKE).animate();\n ```\n4. When needed, you can also update the state with new values. This can be\n part of a tile's [`LoadAction`](/reference/androidx/wear/protolayout/ActionBuilders.LoadAction).\n\n In this example, the water intake value is updated to `400`: \n\n Kotlin \n\n ```kotlin\n val loadAction = LoadAction.Builder()\n .setRequestState(\n State.Builder()\n .addKeyToValueMapping(\n KEY_WATER_INTAKE,\n DynamicDataBuilders.DynamicDataValue.fromInt(400)\n )\n .build()\n )\n .build()\n ```\n\n Java \n\n ```java\n LoadAction loadAction = new LoadAction.Builder()\n .setRequestState(\n new State.Builder()\n .addKeyToValueMapping(\n KEY_WATER_INTAKE,\n DynamicDataBuilders.DynamicDataValue.fromInt(400)\n ).build()\n ).build();\n ```\n\nRecommended for you\n\n- Note: link text is displayed when JavaScript is off\n- [Migrate to ProtoLayout namespaces](/training/wearables/tiles/migrate-to-protolayout)\n- [Get started with tiles](/training/wearables/tiles/get_started)\n- [Other considerations](/develop/ui/compose/migrate/other-considerations)"]]