Untuk mulai menyediakan kartu dari aplikasi, sertakan dependensi berikut dalam file
build.gradle
aplikasi.
Groovy
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.4.0" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.2.0" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.2.0" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.2.0" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.4.0" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.4.0" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.4.0") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.2.0") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.2.0") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.2.0") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.4.0") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.4.0") }
Membuat kartu
Untuk menyediakan kartu dari aplikasi, buat class yang memperluas
TileService
dan implementasikan metode tersebut, seperti ditunjukkan dalam contoh kode berikut:
Kotlin
// Uses the ProtoLayout namespace for tile timeline objects. // If you haven't done so already, migrate to the ProtoLayout namespace. import androidx.wear.protolayout.TimelineBuilders.Timeline import androidx.wear.protolayout.material.Text import androidx.wear.tiles.TileBuilders.Tile private val RESOURCES_VERSION = "1" class MyTileService : TileService() { override fun onTileRequest(requestParams: RequestBuilders.TileRequest) = Futures.immediateFuture(Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( Text.Builder(this, "Hello world!") .setTypography(Typography.TYPOGRAPHY_DISPLAY1) .setColor(argb(0xFF000000.toInt())) .build())) .build()) override fun onTileResourcesRequest(requestParams: ResourcesRequest) = Futures.immediateFuture(Resources.Builder() .setVersion(RESOURCES_VERSION) .build() ) }
Java
// Uses the ProtoLayout namespace for tile timeline objects. // If you haven't done so already, migrate to the ProtoLayout namespace. import androidx.wear.protolayout.TimelineBuilders.Timeline; import androidx.wear.protolayout.material.Text; import androidx.wear.tiles.TileBuilders.Tile; public class MyTileService extends TileService { private static final String RESOURCES_VERSION = "1"; @NonNull @Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( new Text.Builder(this, "Hello world!") .setTypography(Typography.TYPOGRAPHY_DISPLAY1) .setColor(ColorBuilders.argb(0xFF000000)) .build())) .build() ); } @NonNull @Override protected ListenableFuture<Resources> onTileResourcesRequest( @NonNull ResourcesRequest requestParams ) { return Futures.immediateFuture(new Resources.Builder() .setVersion(RESOURCES_VERSION) .build() ); } }
Selanjutnya, tambahkan layanan di dalam tag <application>
file AndroidManifest.xml
Anda.
<service android:name=".MyTileService" android:label="@string/tile_label" android:description="@string/tile_description" android:icon="@drawable/tile_icon_round" android:roundIcon="@drawable/tile_icon_round" android:exported="true" android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER"> <intent-filter> <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" /> </intent-filter> <meta-data android:name="androidx.wear.tiles.PREVIEW" android:resource="@drawable/tile_preview" /> </service>
Filter intent dan izin akan mendaftarkan layanan ini sebagai penyedia kartu.
Ikon, label, dan deskripsi ditampilkan kepada pengguna saat mereka mengonfigurasi kartu di ponsel atau smartwatch.
Gunakan tag metadata pratinjau untuk menampilkan pratinjau kartu saat mengonfigurasinya di ponsel.
Ringkasan siklus proses layanan kartu
Setelah membuat dan mendeklarasikan TileService
dalam manifes aplikasi, Anda
dapat merespons perubahan status layanan kartu.
TileService
adalah layanan terikat. TileService
Anda terikat sebagai hasil
permintaan aplikasi atau jika sistem perlu berkomunikasi dengannya. Siklus proses layanan terikat standar berisi empat metode callback berikut: onCreate()
, onBind()
, onUnbind()
, dan onDestroy()
. Sistem memanggil metode ini setiap kali layanan
memasuki fase siklus proses yang baru.
Selain callback yang mengontrol siklus proses layanan terikat, Anda dapat
mengimplementasikan metode lain yang dikhususkan untuk siklus proses TileService
. Semua layanan
kartu harus mengimplementasikan onTileRequest()
dan onTileResourcesRequest()
untuk
merespons permintaan update dari sistem.
onTileAddEvent()
: Sistem hanya memanggil metode ini saat pengguna menambahkan kartu untuk pertama kalinya, dan jika pengguna menghapus dan menambahkan kartu lagi. Ini adalah waktu terbaik untuk melakukan inisialisasi satu kali.onTileAddEvent()
hanya dipanggil saat kumpulan kartu dikonfigurasi ulang, bukan setiap kali kartu dibuat oleh sistem. Misalnya, saat perangkat dimulai ulang atau dihidupkan,onTileAddEvent()
tidak dipanggil untuk kartu yang telah ditambahkan. Sebagai gantinya, Anda dapat menggunakangetActiveTilesAsync()
untuk mendapatkan snapshot kartu mana milik Anda yang aktif.onTileRemoveEvent()
: Sistem memanggil metode ini hanya jika pengguna menghapus kartu Anda.onTileEnterEvent()
: Sistem memanggil metode ini saat kartu yang disediakan oleh penyedia ini muncul di layar.onTileLeaveEvent()
: Sistem memanggil metode ini saat kartu yang disediakan oleh penyedia ini tidak terlihat di layar.onTileRequest()
: Sistem memanggil metode ini saat sistem meminta linimasa baru dari penyedia ini.onTileResourcesRequest()
: Sistem memanggil metode ini saat sistem meminta paket resource dari penyedia ini. Hal ini dapat terjadi pada saat Kartu pertama dimuat atau setiap kali versi resource berubah.
Mengkueri kartu mana yang aktif
Kotak aktif adalah kotak yang telah ditambahkan untuk ditampilkan di smartwatch. Gunakan
TileService
metode statis getActiveTilesAsync()
untuk mengkueri kartu mana
yang termasuk dalam aplikasi Anda yang aktif.
Membuat UI untuk kartu
Tata letak kartu ditulis menggunakan pola builder. Tata letak kartu dibuat seperti hierarki yang terdiri dari penampung tata letak dan elemen tata letak dasar. Setiap elemen tata letak memiliki properti, yang dapat Anda setel melalui berbagai metode penyetel.
Elemen tata letak dasar
Elemen visual berikut dari library protolayout
didukung,
beserta komponen Material:
Text
: merender string teks, yang digabungkan secara opsional.Image
: merender gambar.Spacer
: menyediakan padding di antara elemen atau dapat berfungsi sebagai pemisah saat Anda menetapkan warna latar belakangnya.
Komponen Material
Selain elemen dasar, library protolayout-material
juga menyediakan komponen yang
memastikan desain kartu sesuai dengan rekomendasi antarmuka pengguna
Desain Material.
Button
: komponen melingkar yang dapat diklik dan dirancang untuk memuat ikon.Chip
: komponen berbentuk elips yang dapat diklik dan dirancang untuk memuat hingga dua baris teks dan ikon opsional.CompactChip
: komponen berbentuk elips yang dapat diklik dan dirancang untuk memuat satu baris teks.TitleChip
: komponen berbentuk elips yang dapat diklik dan mirip denganChip
tetapi lebih tinggi untuk menampung teks judul.CircularProgressIndicator
: indikator progres melingkar yang dapat ditempatkan di dalamEdgeContentLayout
untuk menampilkan progres di sekitar tepi layar.
Penampung tata letak
Penampung berikut didukung, beserta tata letak Material:
Row
: menata letak elemen turunan secara horizontal, satu per satu.Column
: menata letak elemen turunan secara vertikal, satu per satu.Box
: menempatkan elemen turunan satu per satu.Arc
: menata letak elemen turunan dalam lingkaran.Spannable
: menerapkanFontStyles
khusus pada bagian teks beserta teks dan gambar yang disisipkan. Untuk informasi selengkapnya, lihat Spannable.
Setiap penampung dapat berisi satu atau beberapa turunan yang juga dapat berupa
penampung. Misalnya, Column
dapat berisi beberapa elemen Row
sebagai turunan
sehingga menghasilkan tata letak seperti petak.
Sebagai contoh, kartu dengan tata letak penampung dan dua elemen tata letak turunan dapat terlihat seperti ini:
Kotlin
private fun myLayout(): LayoutElement = Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VALIGN_BOTTOM) .addContent(Text.Builder() .setText("Hello world") .build() ) .addContent(Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build()
Java
private LayoutElement myLayout() { return new Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VALIGN_BOTTOM) .addContent(new Text.Builder() .setText("Hello world") .build() ) .addContent(new Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build(); }
Tata letak Material
Selain tata letak dasar, library protolayout-material
juga menyediakan beberapa tata letak
tetap yang dibuat untuk menampung elemen di "slot" tertentu.
PrimaryLayout
: memosisikan satu tindakan utamaCompactChip
di bagian bawah dengan konten yang berpusat di atasnya.MultiSlotLayout
: memosisikan label utama dan sekunder dengan konten opsional di antara keduanya danCompactChip
opsional di bagian bawah.MultiButtonLayout
: mengatur posisi kumpulan tombol yang disusun sesuai dengan pedoman Material.EdgeContentLayout
: mengatur posisi konten di sekitar tepi layar, sepertiCircularProgressIndicator
. Saat menggunakan tata letak ini, margin dan padding yang sesuai secara otomatis diterapkan ke konten di dalamnya.
Arc
Turunan penampung Arc
berikut didukung:
ArcLine
: merender garis melengkung di sekitar Arc.ArcText
: merender teks melengkung di Arc.ArcAdapter
: merender elemen tata letak dasar di Arc, yang digambar bersinggungan dengan Arc.
Untuk informasi selengkapnya, lihat dokumentasi referensi untuk setiap jenis elemen.
Pengubah
Setiap elemen tata letak yang tersedia secara opsional dapat memiliki pengubah yang diterapkan padanya. Gunakan pengubah ini untuk tujuan berikut:
- Mengubah tampilan visual tata letak. Misalnya, tambahkan latar belakang, batas, atau padding ke elemen tata letak.
- Menambahkan metadata tentang tata letak. Misalnya, menambahkan pengubah semantik ke elemen tata letak untuk digunakan dengan pembaca layar.
- Menambahkan fungsi. Misalnya, menambahkan pengubah yang dapat diklik ke elemen tata letak agar kartu Anda interaktif. Untuk mengetahui informasi selengkapnya, lihat Berinteraksi dengan kartu.
Misalnya, kita dapat menyesuaikan metadata dan tampilan default
Image
, seperti yang ditunjukkan
dalam contoh kode berikut:
Kotlin
private fun myImage(): LayoutElement = Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(Modifiers.Builder() .setBackground(Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(Padding.Builder().setStart(dp(12f)).build()) .setSemantics(Semantics.builder() .setContentDescription("Image description") .build() ).build() ).build()
Java
private LayoutElement myImage() { return new Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(new Modifiers.Builder() .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(new Padding.Builder().setStart(dp(12f)).build()) .setSemantics(new Semantics.Builder() .setContentDescription("Image description") .build() ).build() ).build(); }
Spannable
Spannable
adalah jenis penampung khusus yang mengatur tata letak elemen yang mirip dengan
teks. Jenis penampung ini berguna jika Anda ingin menerapkan gaya yang berbeda
ke hanya satu substring dalam blok teks yang lebih besar, dan tidak mungkin dilakukan dengan elemen
Text
.
Penampung Spannable
diisi dengan turunan
Span
. Turunan lain, atau instance Spannable
bertingkat, tidak diizinkan.
Ada dua jenis turunan Span
:
Misalnya, Anda dapat mencetak miring kata "dunia" dalam kartu "Halo dunia" dan menyisipkan gambar di antara kata, seperti yang ditunjukkan dalam contoh kode berikut:
Kotlin
private fun mySpannable(): LayoutElement = Spannable.Builder() .addSpan(SpanText.Builder() .setText("Hello ") .build() ) .addSpan(SpanImage.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .build() ) .addSpan(SpanText.Builder() .setText("world") .setFontStyle(FontStyle.Builder() .setItalic(true) .build()) .build() ).build()
Java
private LayoutElement mySpannable() { return new Spannable.Builder() .addSpan(new SpanText.Builder() .setText("Hello ") .build() ) .addSpan(new SpanImage.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .build() ) .addSpan(new SpanText.Builder() .setText("world") .setFontStyle(newFontStyle.Builder() .setItalic(true) .build()) .build() ).build(); }
Menggunakan resource
Kartu tidak memiliki akses ke resource mana pun di aplikasi Anda. Ini berarti Anda
tidak boleh meneruskan ID gambar Android ke elemen tata letak Image
dan mengharapkannya untuk
diselesaikan. Sebagai gantinya, ganti metode
onTileResourcesRequest()
dan sediakan resource apa pun secara manual.
Terdapat dua cara untuk menyediakan gambar dalam metode onTileResourcesRequest()
:
- Menyediakan resource drawable menggunakan
setAndroidResourceByResId()
. - Menyediakan gambar dinamis sebagai
ByteArray
menggunakansetInlineResource()
.
Kotlin
override fun onTileResourcesRequest( requestParams: ResourcesRequest ) = Futures.immediateFuture( Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", ImageResource.Builder() .setAndroidResourceByResId(AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", ImageResource.Builder() .setInlineResource(InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() )
Java
@Override protected ListenableFuture<Resources> onTileResourcesRequest( @NonNull ResourcesRequest requestParams ) { return Futures.immediateFuture( new Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", new ImageResource.Builder() .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", new ImageResource.Builder() .setInlineResource(new InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() ); }
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Bermigrasi ke namespace ProtoLayout
ConstraintLayout
di Compose- Membuat kartu Setelan Cepat kustom untuk aplikasi Anda