Od wersji 1.2 kafelków możesz przesyłać strumieniowo aktualizacje danych platformy za pomocą dynamicznych wyrażeń. Następnie możesz powiązać te aktualizacje z animacjami w swoich kafelkach. Aplikacja otrzymuje aktualizacje tej wartości co sekundę.
Dzięki wyrażeniom dynamicznym nie musisz odświeżać całego kafelka, gdy zmienia się jego zawartość. Aby zwiększyć zaangażowanie użytkowników, animuj dynamiczne obiekty 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
Buttonobiektu; - Wiele wartości ciągu znaków, w tym zawartość obiektu
Text, zawartość obiektuLayoutElementsBuilders.Texti opis zawartości obiektuCircularProgressIndicator.
Aby użyć wyrażenia dynamicznego jako możliwej wartości elementu w kafelku, użyj odpowiedniego *Prop dynamicznego typu właściwości elementu i przekaż źródło danych do metody setDynamicValue() klasy konstruktora dynamicznego typu właściwości.
Kafelki obsługują te typy właściwości dynamicznych:
- W przypadku wymiarów liniowych mierzonych w pikselach niezależnych od wyświetlacza użyj
DimensionBuilders.DpProp. - W przypadku wymiarów kątowych, mierzonych w stopniach, użyj symbolu
DimensionBuilders.DegreesProp. - W przypadku wartości tekstowych użyj
TypeBuilders.StringProp. - W przypadku wartości kolorów używaj
ColorBuilders.ColorProp. - W przypadku wartości zmiennoprzecinkowych używaj znaku
TypeBuilders.FloatProp.
Jeśli 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 tekstowego. Te ograniczenia pozwalają modułowi renderującemu systemu 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ę zaczynającą się od znaku setLayoutConstraintsForDynamic*.
Poniższy fragment kodu pokazuje, jak wyświetlać aktualizacje tętna za pomocą 3 cyfr z wartością domyślną --:
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żywaj niewielkiej liczby wyrażeń w ramach jednego kafelka.
Wear OS ogranicza liczbę wyrażeń, które może zawierać jeden kafel. Jeśli kafel zawiera zbyt wiele dynamicznych wyrażeń, wartości dynamiczne są ignorowane, a system wraca do wartości statycznych, które podajesz w przypadku poszczególnych typów właściwości dynamicznych.
Zbieranie 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, wykonaj te czynności:
Utwórz zestaw kluczy reprezentujących różne wartości stanu kafelka. W tym przykładzie tworzymy klucze dla ilości wypitej wody i notatki qqq:
companion object { val KEY_WATER_INTAKE = intAppDataKey("key_water_intake") val KEY_NOTE = stringAppDataKey("key_note") }
W implementacji
onTileRequest()wywołaj funkcjęsetState()i utwórz wstępne mapowania każdego klucza na konkretną dynamiczną wartość danych: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ć funkcjęanimate(), aby wyświetlić animację od poprzedniej do bieżącej wartości:val waterIntakeValue = DynamicBuilders.DynamicInt32.from(KEY_WATER_INTAKE)
W razie potrzeby możesz też zaktualizować stan, podając nowe wartości. Może to być część
LoadActionkafelka.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ę