從 Tiles 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*
的方法,在元素層級 (而不是動態運算式層級) 指定這些限制條件。
下列程式碼片段說明如何使用 3 位數 (備用值為 --
) 顯示更新的心率:
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() ); }
在單一資訊方塊中使用少量運算式
Wear OS 對單一資訊方塊可擁有的運算式數量設有限制。如果資訊方塊內含的動態運算式總數過多,系統會忽略這些動態值,改回使用您提供給各個動態屬性類型的靜態值。
由於下列運算式的總數不足,您可以放心將以下這組運算式加入資訊方塊。這樣一來,資訊方塊就會正常運作:
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");
但是,以下資訊方塊可能含有數量過多的運算式:
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) ); }
將動態資料合併為狀態物件
您可以將資料來源提供的最新一組更新內容合併為「狀態」,然後傳送至資訊方塊以進行值轉譯。
如要在資訊方塊中使用狀態資訊,請完成下列步驟:
建立一組鍵,代表資訊方塊的不同狀態值。以下範例建立了代表飲水量和附註的鍵:
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");
在
onTileRequest()
實作中,呼叫setState()
並建立每個鍵與特定動態資料值的初始對應: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() ); }
建立版面配置時,在要顯示狀態資料的位置,使用
Dynamic*
類型物件。您也可以呼叫animate()
,顯示從前一個值轉換成目前值的動畫:Kotlin
DynamicInt32.from(KEY_WATER_INTAKE).animate()
Java
DynamicInt32.from(KEY_WATER_INTAKE).animate();
如有需要,您也可以將狀態更新為新的值。這可以透過資訊方塊的
LoadAction
執行。在以下範例中,飲水量值會更新為
400
:Kotlin
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400))
Java
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400));
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 遷移至 ProtoLayout 命名空間
- 開始使用資訊方塊
- 其他考量