Kartu dapat melakukan lebih dari sekadar menampilkan informasi; kartu juga dapat bersifat interaktif.
Agar elemen seperti textButton()
merespons ketukan, buat pengendali
klik menggunakan clickable()
dan kaitkan dengan elemen tata letak.
Anda dapat mengonfigurasi Clickable
untuk memicu tindakan dengan dua cara utama:
- Meluncurkan aktivitas secara langsung: Gunakan
launchAction()
untuk kasus saat Anda perlu segera membuka aktivitas. - Mendelegasikan ke layanan kartu: Gunakan
loadAction()
untuk memicu logika dalamTileService
. Ini adalah pendekatan yang lebih fleksibel yang memungkinkan Anda memuat ulang konten kartu, memperbarui statusnya, atau meluncurkan aktivitas yang lebih kompleks.
Meluncurkan aktivitas yang diekspor
Jika ketukan pengguna harus segera meluncurkan aktivitas, gunakan launchAction()
.
Berikan ComponentName
untuk mengidentifikasi aktivitas. Aktivitas harus
diekspor. Dengan pendekatan ini, Anda dapat meneruskan tambahan Intent
dengan tindakan.
Namun, Anda tidak dapat menetapkan flag Intent
kustom.
Contoh berikut menunjukkan cara membuat Clickable
untuk meluncurkan TileActivity
dengan dua tambahan, name
dan age
:
textButton( labelContent = { text("launchAction()".layoutString, typography = BODY_LARGE) }, onClick = clickable( action = launchAction( ComponentName( "com.example.wear", "com.example.wear.snippets.m3.tile.TileActivity", ), mapOf( "name" to ActionBuilders.stringExtra("Bartholomew"), "age" to ActionBuilders.intExtra(21), ), ) ), )
Di dalam aktivitas yang diluncurkan, ambil nilai dari tambahan intent:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // When this activity is launched from the tile InteractionLaunchAction, // "name" will be "Bartholomew" and "age" will be 21 val name = intent.getStringExtra("name") val age = intent.getStringExtra("age") // ... }
Menangani interaksi di layanan kartu
Untuk interaksi yang lebih fleksibel, gunakan loadAction()
. Saat pengguna mengetuk
elemen yang dikonfigurasi dengan loadAction
, sistem akan memanggil ulang
TileService.onTileRequest()
Anda. Hal ini memungkinkan Anda menjalankan logika di layanan untuk
memperbarui kartu, mengubah statusnya, dan melakukan tugas yang lebih kompleks.
Memuat ulang konten kartu
Penggunaan loadAction
yang paling sederhana adalah untuk memberi sinyal refresh. Panggil loadAction
tanpa argumen. Saat diketuk, sistem akan memanggil onTileRequest()
, yang memungkinkan
layanan Anda menampilkan tata letak baru dengan konten yang diperbarui.
textButton( onClick = clickable(loadAction()), labelContent = { text("Refresh".layoutString) }, )
Membedakan beberapa elemen interaktif
Jika kartu Anda berisi beberapa elemen interaktif, Anda dapat mengaitkan ID
dengan pengubah Clickable
:
textButton( labelContent = { text("Deep Link me!".layoutString, typography = BODY_LARGE) }, onClick = clickable(id = "foo", action = loadAction()), )
Di dalam onTileRequest()
, Anda dapat memeriksa ID ini menggunakan
requestParams.currentState.lastClickableId
untuk menentukan tindakan yang akan dilakukan.
Contoh: Meluncurkan aktivitas dengan deep link
Pola ini ideal untuk meluncurkan aktivitas dengan deep link. Ketukan pengguna
akan memuat ulang kartu, layanan Anda akan memeriksa ID, lalu meluncurkan aktivitas
baru. Untuk mengontrol data sebelumnya, gunakan TaskStackBuilder
untuk memberikan
pengalaman navigasi yang lebih baik bagi pengguna. Saat pengguna mengetuk elemen, mereka
akan diarahkan langsung ke layar deep link (layar message_detail/1
dari
contoh). Karena .addNextIntentWithParentStack()
digunakan, aktivitas induk juga ditambahkan ke data sebelumnya. Artinya, jika pengguna menggeser
kembali, mereka akan menavigasi ke atas ke layar utama aplikasi (MessageList
dalam
contoh) dan bukan langsung keluar ke kartu. Menggeser kembali untuk kedua kalinya
akan mengembalikannya ke kartu.
override fun onTileRequest( requestParams: RequestBuilders.TileRequest ): ListenableFuture<Tile?> { val lastClickableId = requestParams.currentState.lastClickableId if (lastClickableId == "foo") { TaskStackBuilder.create(this) .addNextIntentWithParentStack( Intent( Intent.ACTION_VIEW, "googleandroidsnippets://app/message_detail/1".toUri(), this, TileActivity::class.java, ) ) .startActivities() } // ... User didn't tap a button (either first load or tapped somewhere else) // ... }
Kemudian, di TileActivity
, konfigurasikan navigasi Anda agar cocok dengan
pola googleandroidsnippets://app/message_detail/{id}
.
AppScaffold { val navController = rememberSwipeDismissableNavController() SwipeDismissableNavHost( navController = navController, startDestination = "message_list", ) { // ... composable( route = "message_detail/{id}", deepLinks = listOf( navDeepLink { uriPattern = "googleandroidsnippets://app/message_detail/{id}" } ), ) { val id = it.arguments?.getString("id") ?: "0" MessageDetails(details = "message $id") } } }
Gunakan TaskStackBuilder
untuk memberikan pengalaman navigasi yang lebih baik bagi pengguna.
Saat pengguna mengetuk elemen, mereka akan diarahkan langsung ke layar deep link—dalam contoh ini, layar tersebut adalah layar message_detail/1
. Karena
.addNextIntentWithParentStack()
digunakan, aktivitas induk juga
ditambahkan ke data sebelumnya. Artinya, jika pengguna menggeser kembali, mereka akan menavigasi
ke layar utama aplikasi—MessageList
dalam contoh—bukan langsung
ke kartu. Men-swipe kembali untuk kedua kalinya akan mengembalikannya ke kartu.
Memperbarui status dalam kartu
Kartu Anda memiliki objek StateBuilders.State
yang menyimpan key-value pair
dan tetap ada di seluruh pemuatan ulang. Anda dapat menggunakan loadAction()
untuk memperbarui status ini
saat pengguna berinteraksi dengan kartu.
Untuk melakukannya, teruskan DynamicDataMap
ke loadAction()
yang berisi nilai
status baru.
textButton( labelContent = { text("loadAction()".layoutString, typography = BODY_LARGE) }, onClick = clickable( action = loadAction( dynamicDataMapOf( stringAppDataKey("name") mapTo "Javier", intAppDataKey("age") mapTo 37, ) ) ), )
Saat onTileRequest()
dipicu oleh tindakan ini, Anda dapat membaca data yang diperbarui
dari requestParams.currentState.stateMap
. Hal ini berguna untuk interaksi
yang secara langsung mengubah data pada kartu, seperti menambahkan penghitung atau mengalihkan
setelan.
override fun onTileRequest( requestParams: RequestBuilders.TileRequest ): ListenableFuture<Tile> { // When triggered by loadAction(), "name" will be "Javier", and "age" will // be 37. with(requestParams.currentState.stateMap) { val name = this[stringAppDataKey("name")] val age = this[intAppDataKey("age")] } // ... }