Mulai Kartu 1.2, Anda dapat melakukan streaming pembaruan data platform menggunakan ekspresi dinamis. Kemudian, Anda dapat mengaitkan pembaruan ini dengan animasi di kartu Anda. Aplikasi Anda mendapatkan pembaruan untuk nilai ini setiap detik.
Dengan menggunakan ekspresi dinamis, Anda tidak perlu me-refresh seluruh kartu saat kontennya berubah. Untuk membuat pengalaman yang lebih menarik di kartu, animasikan objek dinamis tersebut.
Mengaitkan ekspresi dinamis dengan sumber data
Namespace androidx.wear.protolayout
dan androidx.wear.protolayout.material
berisi banyak class yang kolomnya menerima ekspresi dinamis.
Beberapa contohnya meliputi:
- Beberapa nilai panjang, termasuk panjang objek
Arc
dan panjang objekCircularProgressIndicator
. - Warna apa pun, seperti warna konten objek
Button
. - Banyak nilai string, termasukkonten dari objek
Text
, konten dari objekLayoutElementsBuilders.Text
, dan deskripsi konten dari objekCircularProgressIndicator
.
Untuk menggunakan ekspresi dinamis sebagai kemungkinan nilai untuk elemen dalam kartu Anda, gunakan
jenis properti dinamis *Prop
yang sesuai pada elemen dan teruskan sumber
data ke metode setDynamicValue()
class builder
jenis properti dinamis.
Kartu mendukung jenis properti dinamis ini:
- Untuk dimensi linear, yang diukur dalam piksel yang tidak bergantung pada tampilan, gunakan
DimensionBuilders.DpProp
. - Untuk dimensi sudut, yang diukur dalam derajat, gunakan
DimensionBuilders.DegreesProp
. - Untuk nilai string, gunakan
TypeBuilders.StringProp
. - Untuk nilai warna, gunakan
ColorBuilders.ColorProp
. - Untuk nilai floating point, gunakan
TypeBuilders.FloatProp
.
Saat menggunakan ekspresi dinamis yang memengaruhi dimensi fisik—nilai apa pun dalam
kartu kecuali warna—Anda juga harus menentukan kumpulan batasan terkait, seperti
format string. Batasan ini memungkinkan perender sistem menentukan
jumlah ruang maksimum yang dapat menempati nilai dalam kartu Anda. Biasanya, Anda
akan menentukan batasan ini pada tingkat elemen, bukan pada tingkat ekspresi
dinamis, dengan memanggil metode yang dimulai dengan setLayoutConstraintsForDynamic*
.
Cuplikan kode berikut menunjukkan cara menampilkan pembaruan pada detak jantung menggunakan 3
digit, dengan nilai penggantian --
:
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() ); }
Menggunakan sejumlah kecil ekspresi dalam satu kartu
Wear OS menetapkan batas jumlah ekspresi yang dapat dimiliki satu kartu. Jika kartu berisi terlalu banyak ekspresi dinamis total, nilai dinamis akan diabaikan, dan sistem akan kembali ke nilai statis yang Anda berikan ke jenis properti dinamis masing-masing.
Anda dapat dengan aman menambahkan kumpulan ekspresi berikut ke kartu, karena tidak ada banyak ekspresi total. Oleh karena itu, kartu berperilaku dengan benar:
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");
Namun, kartu ini mungkin memiliki terlalu banyak ekspresi:
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) ); }
Menggabungkan data dinamis ke dalam objek status
Anda dapat menggabungkan kumpulan pembaruan terbaru dari sumber data ke dalam status, yang akan diteruskan ke kartu untuk rendering nilai.
Untuk menggunakan informasi status di kartu Anda, selesaikan langkah-langkah berikut:
Tetapkan kumpulan kunci yang mewakili berbagai nilai dari status kartu Anda. Contoh ini membuat kunci untuk asupan air dan catatan:
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");
Dalam penerapan
onTileRequest()
, panggilsetState()
dan tetapkan pemetaan awal dari setiap kunci ke nilai data dinamis tertentu: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() ); }
Saat Anda membuat tata letak, di tempat yang diinginkan untuk menampilkan data ini dari status, gunakan objek jenis
Dynamic*
. Anda juga dapat memanggilanimate()
untuk menampilkan animasi dari nilai sebelumnya ke nilai saat ini:Kotlin
DynamicInt32.from(KEY_WATER_INTAKE).animate()
Java
DynamicInt32.from(KEY_WATER_INTAKE).animate();
Jika diperlukan, Anda juga dapat memperbarui status dengan nilai baru. Status ini dapat menjadi bagian dari
LoadAction
kartu.Dalam contoh ini, nilai asupan air diperbarui menjadi
400
:Kotlin
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400))
Java
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400));
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Bermigrasi ke namespace ProtoLayout
- Mulai menggunakan kartu
- Pertimbangan lainnya