Od wersji 1.2 kafelków możesz przesyłać strumieniowo aktualizacje danych platformy za pomocą dynamicznych wyrażeń. Możesz potem powiązać te aktualizacje z animacjami w kafelkach. Twoja aplikacja otrzymuje aktualizacje tej wartości co sekundę.
Dzięki wyrażeniom dynamicznym nie musisz odświeżać całego kafelka, gdy jego zawartość się zmieni. Aby zwiększyć zaangażowanie użytkowników, animuj obiekty dynamiczne w kafelkach.
Powiązywanie wyrażeń dynamicznych ze źródłami danych
Przestrzenie nazw androidx.wear.protolayout i androidx.wear.protolayout.material
zawierają wiele klas, których pola akceptują wyrażenia dynamiczne. Oto kilka przykładów:
- kilka wartości długości, w tym długość obiektu
Arci długość obiektuCircularProgressIndicator. - dowolny kolor, np. kolor treści obiektu
Button; - wiele wartości ciągów znaków, w tym zawartość obiektu
Text, zawartość obiektuLayoutElementsBuilders.Texti opis treści obiektuCircularProgressIndicator.
Aby użyć wyrażenia dynamicznego jako możliwej wartości elementu w kafelku, użyj odpowiedniego typu właściwości dynamicznej *Prop i przekaż źródło danych do metody setDynamicValue() klasy konstruktora typu właściwości dynamicznej.
Kafelki obsługują te typy właściwości dynamicznych:
- W przypadku wymiarów liniowych mierzonych w pikselach niezależnych od gęstości ekranu użyj
DimensionBuilders.DpProp. - W przypadku wymiarów kątowych mierzonych w stopniach użyj
DimensionBuilders.DegreesProp. - W przypadku wartości ciągów znaków użyj
TypeBuilders.StringProp. - W przypadku wartości kolorów użyj
ColorBuilders.ColorProp. - W przypadku wartości zmiennoprzecinkowych użyj
TypeBuilders.FloatProp.
Gdy używasz wyrażenia dynamicznego, które wpływa na wymiary fizyczne (dowolna wartość w kafelku z wyjątkiem koloru), musisz też określić zestaw powiązanych ograniczeń, np. format ciągu znaków. Te ograniczenia pozwalają systemowemu modułowi renderowania określić maksymalną ilość miejsca, jaką wartość może zajmować w kafelku. Zwykle te ograniczenia określa się na poziomie elementu, a nie na poziomie wyrażenia dynamicznego, wywołując metodę, która zaczyna się od setLayoutConstraintsForDynamic*.
Ten fragment kodu pokazuje, jak wyświetlać aktualizacje tętna za pomocą 3 cyfr z wartością zastępczą --:
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() )
Używanie niewielkiej liczby wyrażeń w jednym kafelku
Wear OS ogranicza liczbę wyrażeń, które może zawierać jeden kafelek. Jeśli kafelek zawiera zbyt wiele wyrażeń dynamicznych, wartości dynamiczne są ignorowane, a system wraca do wartości statycznych, które podajesz w odpowiednich typach właściwości dynamicznych.
Konsolidowanie danych dynamicznych w obiekcie stanu
Najnowszy zestaw aktualizacji ze źródeł danych możesz skonsolidować w stanie, który przekazujesz do kafelka w celu renderowania wartości.
Aby używać informacji o stanie w kafelkach:
Ustal zestaw kluczy, które reprezentują różne wartości stanu kafelka. Ten przykład tworzy klucze do spożycia wody i notatki qqq:
companion object { val KEY_WATER_INTAKE = intAppDataKey("key_water_intake") val KEY_NOTE = stringAppDataKey("key_note") }
W implementacji
onTileRequest()wywołajsetState()i ustal wstępne mapowania każdego klucza na konkretną wartość danych dynamicznych: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() ) }
Podczas tworzenia układu w miejscu, w którym chcesz wyświetlać te dane ze stanu, użyj obiektu typu
Dynamic*. Możesz też wywołaćanimate(), aby wyświetlić animację od poprzedniej wartości do bieżącej:val waterIntakeValue = DynamicBuilders.DynamicInt32.from(KEY_WATER_INTAKE)
W razie potrzeby możesz też zaktualizować stan o nowe wartości. Może to być część kafelka
LoadAction.W tym przykładzie wartość spożycia wody jest aktualizowana do
400:val loadAction = loadAction( dynamicDataMapOf( KEY_WATER_INTAKE mapTo 400, KEY_NOTE mapTo "Outstanding" ) )
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy język JavaScript jest wyłączony.
- Migracja do przestrzeni nazw ProtoLayout
- Pierwsze kroki z kafelkami
- Inne kwestie, które warto wziąć pod uwagę