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() ); }
1 つのタイル内で限られた数の式を使用する
Wear OS では、1 つのタイルに設定できる式の数に上限が設定されています。タイルに含まれる動的式が多すぎる場合、動的な値は無視され、システムはそれぞれの動的プロパティ型で指定された静的な値にフォールバックします。
次の式のセットは式の数が多すぎないため、タイルに問題なく追加できます。その結果、タイルは正常に動作します。
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 名前空間に移行する
- タイルのスタートガイド
- その他の考慮事項