Начиная с версии 1.2, в мозаиках можно использовать динамические выражения для потоковой передачи обновлений данных платформы. Затем вы можете связать эти обновления с анимацией на своих плитках. Приложение получает обновления этого значения каждую секунду.
При использовании динамических выражений вам не нужно обновлять всю плитку, когда меняется ее контент. Чтобы сделать виджеты более привлекательными, добавьте анимацию для динамических объектов.
Как связать динамические выражения с источниками данных
Пространства имен androidx.wear.protolayout и androidx.wear.protolayout.material
содержат множество классов, поля которых принимают динамические выражения. Вот несколько примеров:
- Несколько значений длины, в том числе длина объекта
Arcи длина объектаCircularProgressIndicator. - Любой цвет, например цвет контента объекта
Button. - Многие строковые значения, в том числе контент объекта
Text, контент объектаLayoutElementsBuilders.Textи описание контента объектаCircularProgressIndicator.
Чтобы использовать динамическое выражение в качестве возможного значения для элемента на карточке, примените к элементу соответствующее динамическое свойство типа *Prop и передайте источник данных в метод setDynamicValue() класса конструктора динамического свойства.
Мозаика поддерживает следующие типы динамических свойств:
- Для линейных размеров, измеряемых в пикселях, не зависящих от плотности экрана, используйте
DimensionBuilders.DpProp. - Для угловых размеров, измеряемых в градусах, используйте
DimensionBuilders.DegreesProp. - Для строковых значений используйте
TypeBuilders.StringProp. - Для значений цвета используйте
ColorBuilders.ColorProp. - Для значений с плавающей запятой используйте
TypeBuilders.FloatProp.
Если вы используете динамическое выражение, которое влияет на физические размеры (любое значение в элементе, кроме цвета), вам также необходимо указать набор связанных ограничений, например формат строки. Эти ограничения позволяют системному отрисовщику определить максимальный объем пространства, который может занимать значение в вашем фрагменте. Обычно эти ограничения задаются на уровне элемента, а не динамического выражения, с помощью метода, начинающегося с setLayoutConstraintsForDynamic*.
В приведенном ниже фрагменте кода показано, как отображать данные о пульсе с помощью трех цифр и резервного значения --:
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() )
Используйте небольшое количество выражений в одном элементе.
В Wear OS ограничено количество выражений, которые могут быть в одном виджете. Если в элементе слишком много динамических выражений, динамические значения игнорируются и система возвращается к статическим значениям, которые вы указали для соответствующих типов динамических свойств.
Как объединить динамические данные в объект состояния
Вы можете объединить последние обновления из источников данных в состояние, которое передается на виджет для отрисовки значений.
Чтобы использовать информацию о состоянии в карточках, выполните следующие действия:
Создайте набор ключей, которые представляют разные значения состояния элемента. В этом примере создаются ключи для отслеживания потребления воды и заметки qqq:
companion object { val KEY_WATER_INTAKE = intAppDataKey("key_water_intake") val KEY_NOTE = stringAppDataKey("key_note") }
В реализации
onTileRequest()вызовитеsetState()и установите начальные сопоставления каждого ключа с определенным динамическим значением данных: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() ) }
При создании макета в том месте, где вы хотите показывать данные из состояния, используйте объект типа
Dynamic*. Вы также можете вызвать методanimate(), чтобы показать анимацию перехода от предыдущего значения к текущему:val waterIntakeValue = DynamicBuilders.DynamicInt32.from(KEY_WATER_INTAKE)
При необходимости вы также можете обновить состояние, указав новые значения. Это может быть частью
LoadActionплитки.В этом примере значение параметра "Потребление воды" обновляется до
400:val loadAction = loadAction( dynamicDataMapOf( KEY_WATER_INTAKE mapTo 400, KEY_NOTE mapTo "Outstanding" ) )
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Переход на пространства имен ProtoLayout
- Начало работы с плитками
- Другие причины