Berinteraksi dengan kartu

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:

  1. Meluncurkan aktivitas secara langsung: Gunakan launchAction() untuk kasus saat Anda perlu segera membuka aktivitas.
  2. Mendelegasikan ke layanan kartu: Gunakan loadAction() untuk memicu logika dalam TileService. 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:

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.

Kemudian, di TileActivity, konfigurasikan navigasi Anda agar cocok dengan pola googleandroidsnippets://app/message_detail/{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")]
    }

    // ...
}