Ab Tiles 1.2 können Sie Aktualisierungen von Plattformdaten mit dynamischen Ausdrücken streamen. Sie können diese Aktualisierungen dann mit Animationen in Ihren Kacheln verknüpfen. Ihre App erhält jede Sekunde Updates zu diesem Wert.
Wenn Sie dynamische Ausdrücke verwenden, müssen Sie nicht die gesamte Kachel aktualisieren, wenn sich ihr Inhalt ändert. Um Ihre Kacheln interaktiver zu gestalten, animieren Sie diese dynamischen Objekte.
Dynamische Ausdrücke mit Datenquellen verknüpfen
Die Namespaces androidx.wear.protolayout
und androidx.wear.protolayout.material
enthalten viele Klassen, deren Felder dynamische Ausdrücke akzeptieren.
Hier einige Beispiele:
- Mehrere Längenwerte, darunter die Länge eines
Arc
-Objekts und die Länge einesCircularProgressIndicator
-Objekts. - Beliebige Farbe, z. B. die Inhaltsfarbe eines
Button
-Objekts. - Viele Stringwerte, darunter der Inhalt eines
Text
-Objekts, der Inhalt einesLayoutElementsBuilders.Text
-Objekts und die Inhaltsbeschreibung einesCircularProgressIndicator
-Objekts.
Wenn Sie einen dynamischen Ausdruck als möglichen Wert für ein Element in Ihrer Kachel verwenden möchten, verwenden Sie den entsprechenden dynamischen Eigenschaftstyp *Prop
des Elements und übergeben Sie die Datenquelle an die Builder-Klasse setDynamicValue()
des dynamischen Eigenschaftstyps.
Kacheln unterstützen die folgenden dynamischen Eigenschaftstypen:
- Verwenden Sie für lineare Abmessungen, die in displayunabhängigen Pixeln gemessen werden,
DimensionBuilders.DpProp
. - Verwenden Sie für Winkelabmessungen, gemessen in Grad,
DimensionBuilders.DegreesProp
. - Verwenden Sie für Stringwerte
TypeBuilders.StringProp
. - Verwenden Sie für Farbwerte
ColorBuilders.ColorProp
. - Verwenden Sie
TypeBuilders.FloatProp
für Gleitkommawerte.
Wenn Sie einen dynamischen Ausdruck verwenden, der sich auf physische Dimensionen – also jeden Wert in einer Kachel mit Ausnahme der Farbe – auswirkt, müssen Sie auch eine Reihe zugehöriger Einschränkungen angeben, z. B. ein Stringformat. Diese Einschränkungen ermöglichen es dem System-Renderer, den maximalen Platz zu bestimmen, den ein Wert innerhalb Ihrer Kachel belegen kann. Normalerweise geben Sie diese Einschränkungen auf Elementebene und nicht auf der Ebene dynamischer Ausdrücke an, indem Sie eine Methode aufrufen, die mit setLayoutConstraintsForDynamic*
beginnt.
Das folgende Code-Snippet zeigt, wie Aktualisierungen der Herzfrequenz mit drei Ziffern und dem Fallback-Wert --
angezeigt werden:
Kotlin
import androidx.wear.protolayout.material.Text public 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(), StringLayoutConstraint.Builder("000") .build() ).build() ) ).build() )
Java
import androidx.wear.protolayout.material.Text; @Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes .setTileTimeline(Timeline.fromLayoutElement( new Text.Builder( this, new TypeBuilders.StringProp.Builder("--") .setDynamicValue(PlatformHealthSources.heartRateBpm() .format() .concat(DynamicBuilders.DynamicString.constant(" bpm"))) .build(), new StringLayoutConstraint.Builder("000") .build() ).build()) ).build() ); }
Verwenden Sie eine kleine Anzahl von Ausdrücken innerhalb einer einzelnen Kachel
Wear OS ergibt ein Limit für die Anzahl der Ausdrücke, die eine einzelne Kachel haben kann. Wenn eine Kachel insgesamt zu viele dynamische Ausdrücke enthält, werden dynamische Werte ignoriert und das System greift auf die statischen Werte zurück, die Sie für die jeweiligen dynamischen Attributtypen bereitstellen.
Sie können den folgenden Satz von Ausdrücken sicher zu einer Kachel hinzufügen, da es nicht viele Ausdrücke gibt. Daher verhält sich die Kachel ordnungsgemäß:
Kotlin
val personHealthInfo = DynamicString.constant("This person has walked ") .concat(PlatformHealthSources.dailySteps() .div(1000) .format()) .concat("thousands of steps and has a current heart rate ") .concat(PlatformHealthSources.heartRateBpm() .format()) .concat(" beats per minute")
Java
DynamicString personHealthInfo = DynamicString.constant("This person has walked ") .concat(PlatformHealthSources.dailySteps() .div(1000) .format()) .concat("thousands of steps and has a current heart rate ") .concat(PlatformHealthSources.heartRateBpm() .format()) .concat(" beats per minute");
Diese Kachel kann jedoch zu viele Ausdrücke enthalten:
Kotlin
// Note that this template is applied as many times as the loop iterates. // The system doesn't reuse dynamic expressions. val dynamicStringTemplate = PlatformHealthSources.dailySteps() .div(1000) .format() for (person in people) { // SomeProperty .setDynamicValue( DynamicBuilders.DynamicString.constant("Steps for ") .concat(person) .concat(" are ") .concat(dynamicStringTemplate) ) }
Java
// Note that this template is applied as many times as the loop iterates. // The system doesn't reuse dynamic expressions. DynamicString dynamicStringTemplate = PlatformHealthSources.dailySteps() .div(1000) .format(); for (int i = 0; i < people.size(); i++) { // SomeProperty .setDynamicValue( DynamicBuilders.DynamicString.constant("Steps for ") .concat(people[i]) .concat(" are ") .concat(dynamicStringTemplate) ); }
Dynamische Daten in einem Zustandsobjekt konsolidieren
Sie können die neuesten Aktualisierungen aus Datenquellen in einem Status konsolidieren, den Sie zum Rendern des Werts an Ihre Kachel übergeben.
Führen Sie die folgenden Schritte aus, um Zustandsinformationen in Ihren Kacheln zu verwenden:
Legen Sie eine Reihe von Schlüsseln fest, die die verschiedenen Werte des Kachelstatus darstellen. In diesem Beispiel werden Schlüssel für die Wasseraufnahme und eine Notiz erstellt:
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");
Rufen Sie in der Implementierung von
onTileRequest()
setState()
auf und richten Sie erste Zuordnungen von jedem Schlüssel zu einem bestimmten dynamischen Datenwert ein: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() ); }
Verwenden Sie beim Erstellen des Layouts an einer Stelle, an der die Statusdaten angezeigt werden sollen, ein Objekt des Typs
Dynamic*
. Sie können auchanimate()
aufrufen, um eine Animation vom vorherigen bis zum aktuellen Wert zu sehen:Kotlin
DynamicInt32.from(KEY_WATER_INTAKE).animate()
Java
DynamicInt32.from(KEY_WATER_INTAKE).animate();
Bei Bedarf können Sie den Status auch mit neuen Werten aktualisieren. Dies kann Teil des
LoadAction
einer Kachel sein.In diesem Beispiel wird der Wert für die Wasseraufnahme in
400
aktualisiert:Kotlin
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400))
Java
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400));
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Zu ProtoLayout-Namespaces migrieren
- Erste Schritte mit Ansichten
- Weitere Hinweise