Di perangkat Wear OS, kartu dirender oleh dua komponen utama dengan versi independen. Untuk memastikan kartu aplikasi Anda berfungsi dengan benar di semua perangkat, penting untuk memahami arsitektur yang mendasarinya.
- Library terkait kartu Jetpack: Library ini (termasuk Kartu Wear
dan ProtoLayout Wear) disematkan dalam aplikasi Anda, dan Anda, sebagai developer,
mengontrol versinya. Aplikasi Anda menggunakan library ini untuk membuat
objek
TileBuilder.Tile
(struktur data yang mewakili Kartu Anda) sebagai respons terhadap panggilanonTileRequest()
sistem. - ProtoLayout Renderer: Komponen sistem ini bertanggung jawab untuk merender
objek
Tile
di layar dan menangani interaksi pengguna. Versi renderer tidak dikontrol oleh developer aplikasi dan dapat bervariasi di perangkat, bahkan perangkat dengan hardware yang identik.
Tampilan atau perilaku Kartu dapat bervariasi berdasarkan versi library Jetpack Tiles aplikasi Anda dan versi ProtoLayout Renderer di perangkat pengguna. Misalnya, satu perangkat mungkin mendukung rotasi atau tampilan data detak jantung, dan perangkat lainnya mungkin tidak.
Dokumen ini menjelaskan cara memastikan aplikasi Anda kompatibel dengan berbagai versi library Kartu dan Renderer ProtoLayout, serta cara bermigrasi ke versi library Jetpack yang lebih tinggi.
Pertimbangkan kompatibilitas
Untuk membuat Kartu yang berfungsi dengan benar di berbagai perangkat, Anda harus mempertimbangkan hal berikut.
Mendeteksi versi perender
- Gunakan metode
getRendererSchemaVersion()
dari objekDeviceParameters
yang diteruskan ke metode onTileRequest(). Metode ini menampilkan nomor versi utama dan minor Renderer ProtoLayout di perangkat. - Kemudian, Anda dapat menggunakan logika kondisional dalam implementasi
onTileRequest()
untuk menyesuaikan desain atau perilaku Kartu berdasarkan versi perender yang terdeteksi.- Misalnya, jika animasi tertentu tidak didukung, Anda dapat menampilkan gambar statis.
Anotasi @RequiresSchemaVersion
- Anotasi
@RequiresSchemaVersion
pada metode ProtoLayout menunjukkan versi skema perender minimum yang diperlukan agar metode tersebut berperilaku seperti yang didokumentasikan (contoh).- Meskipun memanggil metode yang memerlukan versi perender yang lebih tinggi daripada yang tersedia di perangkat tidak akan menyebabkan aplikasi Anda error, hal ini dapat menyebabkan konten tidak ditampilkan atau fitur diabaikan.
Contoh
override fun onTileRequest(
requestParams: TileService.TileRequest
): ListenableFuture<Tile> {
val rendererVersion =
requestParams.deviceConfiguration.rendererSchemaVersion
val tile = Tile.Builder()
if (
rendererVersion.major > 1 ||
(rendererVersion.major == 1 && rendererVersion.minor >= 300)
) {
// Use a feature supported in renderer version 1.300 or later
tile.setTileTimeline(/* ... */ )
} else {
// Provide fallback content for older renderers
tile.setTileTimeline(/* ... */ )
}
return Futures.immediateFuture(tile.build())
}
Menguji dengan versi perender yang berbeda
Untuk menguji kartu Anda terhadap versi perender yang berbeda, deploy ke versi emulator Wear OS yang berbeda. (Di perangkat fisik, update ProtoLayout Renderer dikirimkan oleh Play Store atau update sistem. Anda tidak dapat memaksa penginstalan versi perender tertentu.)
Fitur Pratinjau Kartu Android Studio menggunakan perender yang disematkan dalam library Jetpack ProtoLayout yang menjadi dependensi kode Anda, sehingga pendekatan lainnya adalah bergantung pada versi library Jetpack yang berbeda saat menguji kartu.
Bermigrasi ke Kartu 1.5 / ProtoLayout 1.3 (Material 3 Ekspresif)
Update library Jetpack Tile untuk memanfaatkan peningkatan terbaru, termasuk perubahan UI agar Kartu Anda terintegrasi dengan lancar dengan sistem.
Jetpack Tiles 1.5 dan Jetpack ProtoLayout 1.3 memperkenalkan beberapa peningkatan dan perubahan yang signifikan. Ini mencakup:
- API seperti Compose untuk mendeskripsikan UI.
- Komponen Material 3 Ekspresif, termasuk tombol tepi yang menempel di bagian bawah dan dukungan untuk visual yang ditingkatkan: animasi Lottie, lebih banyak jenis gradien, dan gaya garis busur baru. - Catatan: beberapa fitur ini juga dapat digunakan tanpa bermigrasi ke API baru.
Rekomendasi
- Migrasi semua kartu secara bersamaan. Hindari mencampur versi kartu
dalam aplikasi Anda. Meskipun komponen Material 3 berada di artefak
terpisah (
androidx.wear.protolayout:protolayout-material3
)—sehingga secara teknis memungkinkan penggunaan Kartu M2.5 dan M3 di aplikasi yang sama—kami sangat menyarankan agar tidak menggunakan pendekatan ini kecuali jika benar-benar diperlukan (misalnya, jika aplikasi Anda memiliki banyak kartu yang tidak dapat dimigrasikan secara bersamaan). - Gunakan panduan UX Kartu. Mengingat sifat kartu yang sangat terstruktur dan bertemplate, gunakan desain dalam contoh yang ada sebagai titik awal untuk desain Anda sendiri.
- Lakukan pengujian di berbagai ukuran layar dan font. Kartu sering kali berisi informasi yang padat, sehingga teks (terutama saat ditempatkan di tombol) rentan mengalami overflow dan pemangkasan. Untuk meminimalkannya, gunakan komponen bawaan dan hindari penyesuaian yang ekstensif. Uji menggunakan fitur pratinjau kartu Android Studio serta di beberapa perangkat sungguhan.
Proses migrasi
Memperbarui dependensi
Pertama, perbarui file build.gradle.kts
Anda. Update versi dan ubah
dependensi protolayout-material
menjadi protolayout-material3
, seperti yang ditunjukkan:
// In build.gradle.kts
//val tilesVersion = "1.4.1"
//val protoLayoutVersion = "1.2.1"
// Use these versions for M3.
val tilesVersion = "1.5.0-rc01"
val protoLayoutVersion = "1.3.0-rc01"
dependencies {
// Use to implement support for wear tiles
implementation("androidx.wear.tiles:tiles:$tilesVersion")
// Use to utilize standard components and layouts in your tiles
implementation("androidx.wear.protolayout:protolayout:$protoLayoutVersion")
// Use to utilize components and layouts with Material Design in your tiles
// implementation("androidx.wear.protolayout:protolayout-material:$protoLayoutVersion")
implementation("androidx.wear.protolayout:protolayout-material3:$protoLayoutVersion")
// Use to include dynamic expressions in your tiles
implementation("androidx.wear.protolayout:protolayout-expression:$protoLayoutVersion")
// Use to preview wear tiles in your own app
debugImplementation("androidx.wear.tiles:tiles-renderer:$tilesVersion")
// Use to fetch tiles from a tile provider in your tests
testImplementation("androidx.wear.tiles:tiles-testing:$tilesVersion")
}
TileService sebagian besar tetap tidak berubah
Perubahan utama dalam migrasi ini memengaruhi komponen UI. Akibatnya,
penerapan TileService
Anda, termasuk mekanisme pemuatan resource,
harus memerlukan sedikit atau tidak ada modifikasi.
Pengecualian utama melibatkan pelacakan aktivitas kartu: jika aplikasi Anda menggunakan
onTileEnterEvent()
atau onTileLeaveEvent()
, Anda harus bermigrasi ke
onRecentInteractionEventsAsync()
. Mulai API 36, peristiwa ini
akan dikelompokkan.
Menyesuaikan kode pembuatan tata letak
Di ProtoLayout 1.2 (M2.5), metode onTileRequest()
menampilkan
TileBuilders.Tile
. Objek ini berisi berbagai elemen, termasuk
TimelineBuilders.Timeline
, yang pada gilirannya menyimpan LayoutElement
yang mendeskripsikan UI kartu.
Dengan ProtoLayout 1.3 (M3), meskipun struktur dan alur data secara keseluruhan belum
berubah, LayoutElement
kini dibuat menggunakan pendekatan
yang terinspirasi Compose dengan tata letak berdasarkan slot yang ditentukan, yaitu (dari atas ke bawah)
titleSlot
(biasanya untuk judul atau header utama), mainSlot
(untuk
konten inti), dan bottomSlot
(sering kali untuk tindakan seperti tombol tepi atau
informasi tambahan seperti teks singkat). Tata letak ini dibuat oleh
fungsi primaryLayout()
.

Perbandingan fungsi tata letak M2.5 dan M3
M2.5
fun myLayout(
context: Context,
deviceConfiguration: DeviceParametersBuilders.DeviceParameters
) =
PrimaryLayout.Builder(deviceConfiguration)
.setResponsiveContentInsetEnabled(true)
.setContent(
Text.Builder(context, "Hello World!")
.setTypography(Typography.TYPOGRAPHY_BODY1)
.setColor(argb(0xFFFFFFFF.toInt()))
.build()
)
.build()
M3
fun myLayout(
context: Context,
deviceConfiguration: DeviceParametersBuilders.DeviceParameters,
) =
materialScope(context, deviceConfiguration) {
primaryLayout(mainSlot = { text("Hello, World!".layoutString) })
}
Untuk menyoroti perbedaan utamanya:
- Penghapusan Builder. Pola builder tradisional untuk komponen UI Material3 diganti dengan sintaksis yang lebih deklaratif dan terinspirasi Compose. (Komponen non-UI seperti String/Warna/Pengubah juga mendapatkan wrapper Kotlin baru.)
- Fungsi Tata Letak dan Inisialisasi Standar. Tata letak M3 mengandalkan
fungsi struktur dan inisialisasi standar:
materialScope()
danprimaryLayout()
. Fungsi wajib ini melakukan inisialisasi lingkungan M3 (tema, cakupan komponen melaluimaterialScope
) dan menentukan tata letak berbasis slot utama (melaluiprimaryLayout
). Keduanya harus dipanggil tepat sekali per tata letak.
Tema
Warna
Fitur unggulan Material 3 Expressive adalah kartu "tema dinamis" yang mengaktifkan fitur ini (aktif secara default) akan ditampilkan dalam tema yang disediakan sistem (ketersediaan bergantung pada perangkat dan konfigurasi pengguna).
Perubahan lain di M3 adalah perluasan jumlah token warna, yang telah
meningkat dari 4 menjadi 29. Token warna baru dapat ditemukan di
class ColorScheme
.
Tipografi
Serupa dengan M2.5, M3 sangat bergantung pada konstanta ukuran font yang telah ditentukan sebelumnya—sebaiknya
jangan menentukan ukuran font secara langsung. Konstanta ini terletak di
class Typography
dan menawarkan rentang opsi
yang lebih ekspresif yang sedikit diperluas.
Untuk mengetahui detail selengkapnya, lihat Dokumentasi tipografi.
Bentuk
Sebagian besar komponen M3 dapat bervariasi di sepanjang dimensi bentuk serta warna.
textButton
(di mainSlot
) dengan bentuk full
:

textButton yang sama dengan bentuk small
:

Komponen
Komponen M3 secara signifikan lebih fleksibel dan dapat dikonfigurasi daripada komponen M2.5. Jika M2.5 sering kali memerlukan komponen yang berbeda untuk berbagai perlakuan visual, M3 sering kali menggunakan komponen "dasar" yang umum tetapi sangat dapat dikonfigurasi dengan default yang baik.
Prinsip ini berlaku untuk tata letak "root". Di M2.5, ini adalah
PrimaryLayout
atau EdgeContentLayout
. Di M3, setelah satu
MaterialScope
tingkat teratas dibuat, fungsi primaryLayout()
akan dipanggil. Tindakan ini akan menampilkan tata letak root secara langsung (tidak memerlukan builder) dan
menerima LayoutElements
untuk beberapa "slot", seperti titleSlot
, mainSlot
,
dan bottomSlot
. Slot ini dapat diisi dengan komponen UI konkret—seperti
yang ditampilkan oleh text(), button(), atau card()—atau struktur
tata letak, seperti Row
atau Column
dari LayoutElementBuilders
.
Tema mewakili peningkatan M3 utama lainnya. Secara default, elemen UI otomatis mematuhi spesifikasi gaya visual M3 dan mendukung tema dinamis.
M2.5 | M3 |
---|---|
Elemen Interaktif | |
Button atau Chip |
|
Teks | |
Text |
text() |
Indikator Progres | |
CircularProgressIndicator |
circularProgressIndicator() atau segmentedCircularProgressIndicator() |
Tata letak | |
PrimaryLayout atau EdgeContentLayout |
primaryLayout() |
— | buttonGroup() |
Gambar | |
— | icon() , avatarImage() , atau backgroundImage() |
Pengubah
Di M3, Modifiers
, yang Anda gunakan untuk mendekorasi atau menambah komponen, lebih mirip dengan Compose. Perubahan ini dapat mengurangi boilerplate dengan secara otomatis
membuat
jenis internal yang sesuai. (Perubahan ini ortogonal dengan penggunaan komponen UI
M3; jika perlu, Anda dapat menggunakan pengubah gaya builder dari
ProtoLayout 1.2 dengan komponen UI M3, dan sebaliknya.)
M2.5
// A Builder-style modifier to set the opacity of an element to 0.5
fun myModifier(): ModifiersBuilders.Modifiers =
ModifiersBuilders.Modifiers.Builder()
.setOpacity(TypeBuilders.FloatProp.Builder(0.5F).build())
.build()
M3
// The equivalent Compose-like modifier is much simpler
fun myModifier(): LayoutModifier = LayoutModifier.opacity(0.5F)
Anda dapat membuat pengubah menggunakan gaya API, dan Anda juga dapat menggunakan
fungsi ekstensi toProtoLayoutModifiers()
untuk mengonversi
LayoutModifier
menjadi ModifiersBuilders.Modifier
.
Fungsi Bantuan
Meskipun ProtoLayout 1.3 memungkinkan banyak komponen UI diekspresikan menggunakan
API yang terinspirasi Compose, elemen tata letak dasar seperti baris dan
kolom dari LayoutElementBuilders
terus menggunakan pola
builder. Untuk menjembatani kesenjangan gaya ini dan mendorong konsistensi dengan
API komponen M3 baru, pertimbangkan untuk menggunakan fungsi bantuan.
Tanpa Helper
primaryLayout(
mainSlot = {
LayoutElementBuilders.Column.Builder()
.setWidth(expand())
.setHeight(expand())
.addContent(text("A".layoutString))
.addContent(text("B".layoutString))
.addContent(text("C".layoutString))
.build()
}
)
Dengan Helper
// Function literal with receiver helper function
fun column(builder: Column.Builder.() -> Unit) =
Column.Builder().apply(builder).build()
primaryLayout(
mainSlot = {
column {
setWidth(expand())
setHeight(expand())
addContent(text("A".layoutString))
addContent(text("B".layoutString))
addContent(text("C".layoutString))
}
}
)
Bermigrasi ke Tiles 1.2 / ProtoLayout 1.0
Mulai versi 1.2, sebagian besar API tata letak Kartu berada di namespace
androidx.wear.protolayout
. Untuk menggunakan API terbaru, selesaikan langkah-langkah migrasi berikut dalam
kode Anda.
Memperbarui dependensi
Dalam file build modul aplikasi Anda, buat perubahan berikut:
Groovy
// Removeimplementation 'androidx.wear.tiles:tiles-material:version'// Include additional dependencies implementation "androidx.wear.protolayout:protolayout:1.2.1" implementation "androidx.wear.protolayout:protolayout-material:1.2.1" implementation "androidx.wear.protolayout:protolayout-expression:1.2.1" // Update implementation "androidx.wear.tiles:tiles:1.4.1"
Kotlin
// Removeimplementation("androidx.wear.tiles:tiles-material:version")// Include additional dependencies implementation("androidx.wear.protolayout:protolayout:1.2.1") implementation("androidx.wear.protolayout:protolayout-material:1.2.1") implementation("androidx.wear.protolayout:protolayout-expression:1.2.1") // Update implementation("androidx.wear.tiles:tiles:1.4.1")
Memperbarui namespace
Di file kode berbasis Kotlin dan Java aplikasi Anda, lakukan pembaruan berikut. Bisa juga dengan mengeksekusi skrip penggantian nama namespace ini.
- Ganti semua impor
androidx.wear.tiles.material.*
denganandroidx.wear.protolayout.material.*
. Selesaikan juga langkah ini untuk libraryandroidx.wear.tiles.material.layouts
. Ganti sebagian besar impor
androidx.wear.tiles.*
lainnya denganandroidx.wear.protolayout.*
.Impor untuk
androidx.wear.tiles.EventBuilders
,androidx.wear.tiles.RequestBuilders
,androidx.wear.tiles.TileBuilders
, danandroidx.wear.tiles.TileService
harus tetap sama.Ganti nama beberapa metode yang tidak digunakan lagi dari class TileService dan TileBuilder:
TileBuilders
:getTimeline()
kegetTileTimeline()
, dansetTimeline()
kesetTileTimeline()
TileService
:onResourcesRequest()
keonTileResourcesRequest()
RequestBuilders.TileRequest
:getDeviceParameters()
kegetDeviceConfiguration()
,setDeviceParameters()
kesetDeviceConfiguration()
,getState()
kegetCurrentState()
, dansetState()
kesetCurrentState()