1. Pengantar
Pengguna dapat berinteraksi dengan aplikasi Anda menggunakan keyboard hardware, biasanya di perangkat layar besar seperti tablet dan perangkat ChromeOS, tetapi juga di perangkat XR. Pengguna harus dapat menavigasi aplikasi Anda dengan efektif menggunakan keyboard hardware seperti halnya menggunakan layar sentuh. Selain itu, saat mendesain aplikasi untuk layar TV dan mobil, yang mungkin tidak memiliki input sentuh dan mengandalkan D-pad atau encoder putar, Anda perlu menerapkan prinsip navigasi keyboard yang serupa.
Compose memungkinkan Anda menangani input dari keyboard hardware, D-pad, dan encoder putar dengan cara yang terpadu. Prinsip utama pengalaman pengguna yang baik untuk metode input ini adalah pengguna dapat memindahkan fokus keyboard secara intuitif dan konsisten ke komponen interaktif yang ingin mereka gunakan.
Dalam codelab ini, Anda akan mempelajari hal-hal berikut:
- Cara menerapkan pola pengelolaan fokus keyboard umum untuk navigasi yang intuitif dan konsisten
- Cara menguji apakah gerakan fokus keyboard berperilaku seperti yang diharapkan
Prasyarat
- Pengalaman membangun aplikasi dengan Compose
- Pengetahuan dasar tentang Kotlin, termasuk lambda dan coroutine
Yang Anda bangun
Anda menerapkan pola pengelolaan fokus keyboard standar berikut:
- Gerakan fokus keyboard — Dari awal hingga akhir, atas ke bawah dalam pola berbentuk z
- Fokus awal yang logis — Tetapkan fokus ke elemen UI yang kemungkinan besar akan digunakan pengguna Anda
- Pemulihan fokus — Pindahkan fokus ke elemen UI yang sebelumnya digunakan pengguna
Yang akan Anda pelajari
- Dasar-dasar pengelolaan fokus di Compose
- Cara membuat elemen UI sebagai target fokus
- Cara meminta fokus untuk memindahkan elemen UI
- Cara memindahkan fokus keyboard ke elemen UI tertentu dalam grup elemen UI
Yang Anda perlukan
- Android Studio Ladybug atau versi yang lebih baru
- Salah satu perangkat berikut untuk menjalankan aplikasi contoh:
- Perangkat layar besar dengan keyboard hardware
- Perangkat virtual Android untuk perangkat layar besar, seperti emulator yang dapat diubah ukurannya
2. Siapkan
- Buat clone repositori GitHub codelab layar besar:
git clone https://github.com/android/large-screen-codelabs
Anda juga dapat mendownload dan membatalkan pengarsipan file ZIP codelab layar besar:
- Buka folder
focus-management-in-compose
. - Di Android Studio, buka project tersebut. Folder
focus-management-in-compose
berisi satu project. - Jika Anda tidak memiliki tablet Android, perangkat foldable, atau perangkat ChromeOS dengan keyboard hardware, buka Pengelola Perangkat di Android Studio, lalu buat perangkat Resizable dalam kategori Phone.
Gambar 1. Mengonfigurasi emulator yang dapat diubah ukurannya di Android Studio.
3. Mempelajari kode awal
Project ini memiliki dua modul:
- start — Berisi kode awal project. Anda membuat perubahan pada kode ini untuk menyelesaikan codelab.
- solution — Berisi kode yang sudah selesai untuk codelab ini.
Aplikasi contoh terdiri dari tiga tab:
- Target fokus
- Urutan traversal fokus
- Grup fokus
Tab target fokus ditampilkan saat aplikasi diluncurkan.
Gambar 2. Tab Focus target ditampilkan saat aplikasi diluncurkan.
Paket ui
berisi kode UI berikut yang dapat Anda gunakan:
App.kt
— Mengimplementasikan tabtab.FocusTargetTab.kt
— Berisi kode untuk tab target fokustab.FocusTraversalOrderTab.kt
— Berisi kode untuk tab urutan traversal fokustab.FocusGroup.kt
— Berisi kode untuk tab grup fokusFocusGroupTabTest.kt
— Pengujian instrumentasi untuktab.FocusTargetTab.kt
)File terletak di folderandroidTest
)
4. Target fokus
Target fokus adalah elemen UI yang dapat difokuskan oleh keyboard. Pengguna dapat memindahkan fokus keyboard dengan tombol Tab
atau tombol arah (panah):
- Tombol
Tab
— Fokus berpindah ke target fokus berikutnya atau target fokus sebelumnya secara satu dimensi. - Tombol arah — Fokus dapat dipindahkan secara dua dimensi: atas, bawah, kiri, dan kanan.
Tab adalah target fokus. Dalam aplikasi contoh, latar belakang tab diperbarui secara visual saat tab memperoleh fokus.
Gambar 3. Latar belakang komponen berubah saat fokus berpindah ke target fokus.
Elemen UI interaktif adalah target fokus secara default
Komponen interaktif adalah target fokus secara default. Dengan kata lain, elemen UI adalah target fokus jika pengguna dapat mengetuknya.
Aplikasi contoh memiliki tiga kartu di tab Focus target. Kartu ke-1 dan kartu ke-3 adalah target fokus; bukan kartu ke-2. Latar belakang kartu ke-3 diperbarui saat pengguna memindahkan fokus dari kartu ke-1 dengan tombol Tab
.
Gambar 4. Target fokus aplikasi mengecualikan kartu ke-2.
Mengubah kartu ke-2 menjadi target fokus
Anda dapat menjadikan kartu ke-2 sebagai target fokus dengan mengubahnya menjadi elemen UI interaktif. Cara termudah adalah dengan menggunakan pengubah clickable
sebagai berikut:
- Buka
FocusTargetTab.kt
dalam pakettabs
- Ubah composable
SecondCard
dengan pengubahclickable
sebagai berikut:
@Composable
fun FocusTargetTab(
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier
) {
FirstCard(
onClick = onClick,
modifier = Modifier.width(240.dp)
)
SecondCard(
modifier = Modifier
.width(240.dp)
.clickable(onClick = onClick)
)
ThirdCard(
onClick = onClick,
modifier = Modifier.width(240.dp)
)
}
}
Menjalankan aplikasi
Sekarang, pengguna dapat memindahkan fokus ke kartu ke-2 selain kartu ke-1 dan kartu ke-3. Anda dapat mencobanya di tab Focus target; pastikan Anda dapat memindahkan fokus dari kartu ke-1 ke kartu ke-2 menggunakan tombol Tab
.
Gambar 5. Memindahkan fokus dari kartu ke-1 ke kartu ke-2 dengan tombol Tab
.
5. Traversal fokus dalam pola berbentuk z
Pengguna mengharapkan fokus keyboard berpindah dari kiri ke kanan dan dari atas ke bawah dalam setelan bahasa kiri ke kanan. Urutan traversal fokus ini disebut pola berbentuk z.
Namun, Compose mengabaikan tata letak saat menentukan target fokus berikutnya dari tombol Tab
dan sebagai gantinya menggunakan traversal fokus satu dimensi berdasarkan urutan panggilan fungsi composable.
Traversal fokus satu dimensi
Urutan traversal fokus satu dimensi berasal dari urutan panggilan fungsi composable, bukan tata letak aplikasi.
Di aplikasi contoh, fokus berpindah dalam urutan berikut di tab Focus traversal order:
- Kartu ke-1
- Kartu ke-4
- Kartu ke-3
- Kartu ke-2
Gambar 6. Traversal fokus mengikuti urutan fungsi composable.
Fungsi FocusTraversalOrderTab
mengimplementasikan tab Focus traversal aplikasi contoh. Fungsi ini memanggil fungsi composable untuk kartu: FirstCard
, FourthCard
, ThirdCard
, dan SecondCard
, dalam urutan tersebut.
@Composable
fun FocusTraversalOrderTab(
modifier: Modifier = Modifier
) {
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
FirstCard(
onClick = onClick,
modifier = Modifier.width(240.dp)
)
FourthCard(
onClick = onClick,
modifier = Modifier
.width(240.dp)
.offset(x = 256.dp)
)
ThirdCard(
onClick = onClick,
modifier = Modifier
.width(240.dp)
.offset(y = (-151).dp)
)
}
SecondCard(
modifier = Modifier.width(240.dp)
)
}
}
Gerakan fokus dalam pola berbentuk z
Anda dapat mengintegrasikan gerakan fokus berbentuk z di tab Focus traversal order aplikasi contoh dengan langkah-langkah berikut:
- Buka
tabs.FocusTraversalOrderTab.kt
- Hapus pengubah offset dari composable
ThirdCard
danFourthCard
. - Ubah tata letak tab menjadi satu kolom dengan dua baris dari satu baris dengan dua kolom.
- Pindahkan composable
FirstCard
danSecondCard
ke baris pertama. - Pindahkan composable
ThirdCard
danFourthCard
ke baris kedua.
Kode yang diubah adalah sebagai berikut:
@Composable
fun FocusTraversalOrderTab(
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier
) {
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
FirstCard(
onClick = onClick,
modifier = Modifier.width(240.dp),
)
SecondCard(
onClick = onClick,
modifier = Modifier.width(240.dp)
)
}
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
ThirdCard(
onClick = onClick,
modifier = Modifier.width(240.dp)
)
FourthCard(
onClick = onClick,
modifier = Modifier.width(240.dp)
)
}
}
}
Menjalankan aplikasi
Sekarang, pengguna dapat memindahkan fokus dari kanan ke kiri, atas ke bawah dalam pola berbentuk z. Anda dapat mencobanya di tab Focus traversal order dan mengonfirmasi bahwa fokus berpindah dalam urutan berikut dengan tombol Tab
:
- Kartu ke-1
- Kartu ke-2
- Kartu ke-3
- Kartu ke-4
Gambar 7. Traversal fokus dalam pola berbentuk z.
6. focusGroup
Fokus berpindah ke kartu ke-3 dari kartu ke-1 dengan tombol arah right
di tab Focus group. Gerakan ini mungkin sedikit membingungkan bagi pengguna karena kedua kartu tidak berdampingan.
Gambar 8. Gerakan fokus yang tidak terduga dari kartu ke-1 ke kartu ke-3.
Traversal fokus dua dimensi mengacu pada informasi tata letak
Menekan tombol arah akan memicu traversal fokus dua dimensi. Ini adalah traversal fokus umum di TV saat pengguna berinteraksi dengan aplikasi Anda menggunakan D-pad. Menekan tombol panah keyboard juga memicu traversal fokus dua dimensi karena tombol tersebut meniru navigasi dengan D-pad.
Dalam traversal fokus dua dimensi, sistem merujuk pada informasi geometris elemen UI dan menentukan target fokus untuk memindahkan fokus. Misalnya, fokus berpindah ke kartu ke-1 dari tab target fokus dengan tombol arah down
, dan menekan tombol arah atas akan memindahkan fokus ke tab target fokus.
Gambar 9. Traversal fokus dengan tombol arah bawah dan atas.
Traversal fokus dua dimensi tidak digabungkan, berbeda dengan traversal fokus satu dimensi dengan tombol Tab
. Misalnya, pengguna tidak dapat memindahkan fokus dengan tombol bawah saat kartu ke-2 difokuskan.
Gambar 10. Tombol arah bawah tidak dapat memindahkan fokus saat kartu ke-2 difokuskan.
Target fokus berada pada tingkat yang sama
Kode berikut mengimplementasikan layar yang disebutkan di atas. Ada empat target fokus: FirstCard
, SecondCard
, ThirdCard
, dan FourthCard
. Keempat target fokus ini berada di tingkat yang sama, dan ThirdCard
adalah item pertama di sebelah kanan FirstCard
dalam tata letak. Itulah sebabnya fokus berpindah ke kartu ke-3 dari kartu ke-1 dengan tombol arah right
.
@Composable
fun FocusGroupTab(
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier,
) {
FirstCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
SecondCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
ThirdCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
FourthCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
}
}
}
Mengelompokkan target fokus dengan pengubah focusGroup
Anda dapat mengubah gerakan fokus yang membingungkan dengan langkah-langkah berikut:
- Buka
tabs.FocusGroup.kt
- Ubah fungsi composable
Column
dalam fungsi composableFocusGroupTab
dengan pengubahfocusGroup
.
Kode yang diperbarui adalah sebagai berikut:
@Composable
fun FocusGroupTab(
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier,
) {
FirstCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.focusGroup(),
) {
SecondCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
ThirdCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
FourthCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
}
}
}
Pengubah focusGroup
membuat grup fokus yang terdiri dari target fokus dalam komponen yang diubah. Target fokus dalam grup fokus dan target fokus di luar grup fokus berada pada tingkat yang berbeda, dan tidak ada target fokus yang ditempatkan di sisi kanan composable FirstCard
. Akibatnya, fokus tidak akan berpindah ke kartu apa pun dari kartu ke-1 dengan tombol arah right
.
Menjalankan aplikasi
Sekarang, fokus tidak berpindah ke kartu ke-3 dari kartu ke-1 dengan tombol arah right
di tab Focus group aplikasi contoh.
7. Meminta fokus
Pengguna tidak dapat menggunakan keyboard atau D-pad untuk memilih elemen UI arbitrer yang akan digunakan. Pengguna perlu memindahkan fokus keyboard ke komponen interaktif sebelum berinteraksi dengan elemen.
Misalnya, pengguna harus memindahkan fokus dari tab Focus target ke kartu ke-1 sebelum berinteraksi dengan kartu. Anda dapat mengurangi jumlah tindakan untuk memulai tugas utama pengguna dengan menetapkan fokus awal secara logis.
Gambar 11. Tiga penekanan tombol Tab
akan memindahkan fokus ke kartu ke-1.
Meminta fokus dengan FocusRequester
Anda dapat meminta fokus untuk memindahkan elemen UI dengan FocusRequester
. Objek FocusRequester
harus dikaitkan dengan elemen UI sebelum memanggil metode requestFocus()
.
Menetapkan fokus awal ke kartu ke-1
Anda dapat menetapkan fokus awal ke kartu ke-1 dengan langkah-langkah berikut:
- Buka
tabs.FocusTarget.kt
- Deklarasikan nilai
firstCard
dalam fungsi composableFocusTargetTab
, dan lakukan inisialisasi nilai dengan objekFocusRequester
yang ditampilkan dari fungsiremember
. - Ubah fungsi composable
FirstCard
dengan pengubahfocusRequester
. - Tentukan nilai
firstCard
sebagai argumen pengubahfocusRequester
. - Panggil fungsi composable
LaunchedEffect
dengan nilaiUnit
, dan panggil metode requestFocus() pada nilaifirstCard
di lambda yang diteruskan ke fungsi composableLaunchedEffect
.
Objek FocusRequester
dibuat dan dikaitkan dengan elemen UI pada langkah kedua dan ketiga. Pada langkah kelima, fokus diminta untuk berpindah ke elemen UI terkait saat composable FocusdTargetTab
disusun untuk pertama kalinya.
Kode yang diperbarui terlihat seperti berikut:
@Composable
fun FocusTargetTab(
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
val firstCard = remember { FocusRequester() }
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier
) {
FirstCard(
onClick = onClick,
modifier = Modifier
.width(240.dp)
.focusRequester(focusRequester = firstCard)
)
SecondCard(
modifier = Modifier
.width(240.dp)
.clickable(onClick = onClick)
)
ThirdCard(
onClick = onClick,
modifier = Modifier.width(240.dp)
)
}
LaunchedEffect(Unit) {
firstCard.requestFocus()
}
}
Menjalankan aplikasi
Sekarang, fokus keyboard berpindah ke Kartu ke-1 di tab Focus target saat tab dipilih. Anda dapat mencobanya dengan beralih tab. Selain itu, kartu ke-1 dipilih saat aplikasi diluncurkan.
Gambar 12. Fokus akan berpindah ke Kartu ke-1 saat tab Focus target dipilih.
8. Memindahkan fokus ke tab yang dipilih
Anda dapat menentukan target fokus saat fokus keyboard memasuki grup fokus. Misalnya, Anda dapat memindahkan fokus ke tab yang dipilih saat pengguna memindahkan fokus ke baris tab.
Anda dapat menerapkan perilaku ini dengan langkah-langkah berikut:
- Buka
App.kt
. - Deklarasikan nilai
focusRequesters
dalam fungsi composableApp
. - Lakukan inisialisasi nilai
focusRequesters
dengan nilai yang ditampilkan dari fungsiremember
yang menampilkan daftar objekFocusRequester
. Panjang daftar yang ditampilkan harus sama dengan panjangScreens.entries
. - Kaitkan setiap objek
FocusRequester
dari nilaifocusRequester
dengan composableTab
dengan mengubah composable Tab dengan pengubahfocusRequester
. - Ubah composable PrimaryTabRow dengan pengubah
focusProperties
dan pengubahfocusGroup
. - Teruskan lambda ke pengubah
focusProperties
, dan kaitkan propertienter
dengan lambda lain. - Tampilkan FocusRequester, yang diindeks dengan nilai
selectedTabIndex
dalam nilaifocusRequesters
, dari lambda yang terkait dengan propertienter
.
Kode yang diubah akan terlihat seperti berikut:
@Composable
fun App(
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
var selectedScreen by rememberSaveable { mutableStateOf(Screen.FocusTarget) }
val selectedTabIndex = Screen.entries.indexOf(selectedScreen)
val focusRequesters = remember {
List(Screen.entries.size) { FocusRequester() }
}
Column(modifier = modifier) {
PrimaryTabRow(
selectedTabIndex = selectedTabIndex,
modifier = Modifier
.focusProperties {
enter = {
focusRequesters[selectedTabIndex]
}
}
.focusGroup()
) {
Screen.entries.forEachIndexed { index, screen ->
Tab(
selected = screen == selectedScreen,
onClick = { selectedScreen = screen },
text = { Text(stringResource(screen.title)) },
modifier = Modifier.focusRequester(focusRequester = focusRequesters[index])
)
}
}
when (selectedScreen) {
Screen.FocusTarget -> {
FocusTargetTab(
onClick = context::onCardClicked,
modifier = Modifier.padding(32.dp),
)
}
Screen.FocusTraversalOrder -> {
FocusTraversalOrderTab(
onClick = context::onCardClicked,
modifier = Modifier.padding(32.dp)
)
}
Screen.FocusRestoration -> {
FocusGroupTab(
onClick = context::onCardClicked,
modifier = Modifier.padding(32.dp)
)
}
}
}
}
Anda dapat mengontrol gerakan fokus dengan pengubah focusProperties
. Dalam lambda yang diteruskan ke pengubah, ubah FocusProperties, yang dirujuk saat sistem memilih target fokus saat pengguna menekan tombol Tab
atau tombol arah saat elemen UI yang diubah difokuskan.
Saat Anda menetapkan properti enter
, sistem akan mengevaluasi lambda yang ditetapkan ke properti dan berpindah ke elemen UI yang dikaitkan dengan objek FocusRequester
yang ditampilkan oleh lambda yang dievaluasi.
Menjalankan aplikasi
Sekarang, fokus keyboard berpindah ke tab yang dipilih saat pengguna memindahkan fokus ke baris tab. Anda dapat mencobanya dengan langkah-langkah berikut:
- Menjalankan aplikasi
- Pilih tab Focus group
- Pindahkan fokus ke kartu ke-1 dengan tombol arah
down
. - Pindahkan fokus dengan tombol arah
up
.
Gambar 13. Fokus akan berpindah ke tab yang dipilih.
9. Pemulihan fokus
Pengguna berharap dapat melanjutkan tugas dengan mudah saat terganggu. Pemulihan fokus mendukung pemulihan dari gangguan. Pemulihan fokus akan memindahkan fokus keyboard ke elemen UI yang sebelumnya dipilih.
Kasus penggunaan umum pemulihan fokus adalah layar utama aplikasi streaming video. Layar memiliki beberapa daftar konten video, seperti film dalam kategori atau episode acara TV. Pengguna melihat-lihat daftar dan menemukan konten yang menarik. Terkadang, pengguna kembali ke daftar yang sebelumnya dilihat dan terus menjelajahi daftar tersebut. Dengan pemulihan fokus, pengguna dapat terus menjelajah tanpa memindahkan fokus keyboard ke item terakhir yang mereka lihat dalam daftar.
Pengubah focusRestorer memulihkan fokus ke grup fokus
Gunakan pengubah focusRestorer
untuk menyimpan dan memulihkan fokus ke grup fokus. Saat fokus keluar dari grup fokus, fokus akan menyimpan referensi ke item yang sebelumnya difokuskan. Kemudian, saat fokus kembali memasuki grup fokus, fokus akan dipulihkan ke item yang sebelumnya difokuskan.
Mengintegrasikan pemulihan fokus dengan tab Focus group
Tab Focus group aplikasi contoh memiliki baris yang berisi kartu ke-2, kartu ke-3, dan kartu ke-4.
Gambar 14. Grup fokus yang berisi kartu ke-2, kartu ke-3, dan kartu ke-4.
Anda dapat mengintegrasikan pemulihan fokus di baris dengan langkah-langkah berikut:
- Buka
tab.FocusGroupTab.kt
- Ubah composable
Row
dalam composableFocusGroupTab
dengan pengubahfocusRestorer
. Pengubah harus dipanggil sebelum pengubahfocusGroup
.
Kode yang diubah akan terlihat seperti berikut:
@Composable
fun FocusGroupTab(
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier,
) {
FirstCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
.focusRestorer()
.focusGroup(),
) {
SecondCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
ThirdCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
FourthCard(
onClick = onClick,
modifier = Modifier.width(208.dp)
)
}
}
}
Menjalankan aplikasi
Sekarang, baris di tab Focus group akan memulihkan fokus, dan Anda dapat mencobanya dengan langkah-langkah berikut:
- Pilih tab Focus group
- Pindahkan fokus ke kartu ke-1
- Pindahkan fokus ke kartu ke-4 dengan tombol
Tab
- Pindahkan fokus ke kartu ke-1 dengan tombol arah
up
- Tekan tombol
Tab
Fokus keyboard berpindah ke kartu ke-4 saat pengubah focusRestorer
menyimpan referensi kartu dan memulihkan fokus saat fokus keyboard memasuki grup fokus yang ditetapkan ke baris.
Gambar 15. Fokus kembali ke kartu ke-4 setelah tombol arah atas ditekan, diikuti dengan menekan tombol Tab
.
10. Menulis pengujian
Anda dapat menguji pengelolaan fokus keyboard yang diterapkan dengan pengujian. Compose menyediakan API untuk menguji apakah elemen UI difokuskan dan melakukan penekanan tombol pada komponen UI. Lihat codelab Pengujian di Jetpack Compose untuk mengetahui informasi selengkapnya.
Menguji tab Target fokus
Anda telah mengubah fungsi composable FocusTargetTab
untuk menetapkan kartu ke-2 sebagai target fokus di bagian sebelumnya. Tulis pengujian implementasi yang Anda lakukan secara manual di bagian sebelumnya. Pengujian dapat ditulis dengan langkah-langkah berikut:
- Buka
FocusTargetTabTest.kt
. Anda akan mengubah fungsitestSecondCardIsFocusTarget
dalam langkah-langkah berikut. - Minta fokus untuk berpindah ke kartu ke-1 dengan memanggil metode
requestFocus
melalui objekSemanticsNodeInteraction
untuk kartu ke-1. - Pastikan kartu ke-1 difokuskan dengan metode
assertIsFocused()
. - Lakukan penekanan tombol
Tab
dengan memanggil metodepressKey
dengan nilaiKey.Tab
dalam lambda yang diteruskan ke metodeperformKeyInput
. - Uji apakah fokus keyboard berpindah ke kartu ke-2 dengan memanggil metode
assertIsFocused()
melalui objekSemanticsNodeInteraction
untuk kartu ke-2.
Kode yang diperbarui terlihat seperti berikut:
@OptIn(ExperimentalTestApi::class, ExperimentalComposeUiApi::class)
@Test
fun testSecondCardIsFocusTarget() {
composeTestRule.setContent {
LocalInputModeManager
.current
.requestInputMode(InputMode.Keyboard)
FocusTargetTab(onClick = {})
}
val context = InstrumentationRegistry.getInstrumentation().targetContext
// Ensure the 1st card is focused
composeTestRule
.onNodeWithText(context.getString(R.string.first_card))
.requestFocus()
.performKeyInput { pressKey(Key.Tab) }
// Test if focus moves to the 2nd card from the 1st card with Tab key
composeTestRule
.onNodeWithText(context.getString(R.string.second_card))
.assertIsFocused()
}
Menjalankan aplikasi
Anda dapat menjalankan pengujian dengan mengklik ikon segitiga yang ditampilkan di sebelah kiri deklarasi class FocusTargetTest
. Lihat bagian Menjalankan pengujian di Pengujian di Android Studio untuk mengetahui informasi selengkapnya.
11. Selamat
Bagus! Anda telah mempelajari elemen penyusun untuk pengelolaan fokus keyboard:
- Target fokus
- Traversal fokus
Anda dapat mengontrol urutan traversal fokus dengan pengubah Compose berikut:
- Pengubah
focusGroup
- Pengubah
focusProperties
Anda telah menerapkan pola umum untuk UX dengan keyboard hardware, fokus awal, dan pemulihan fokus. Pola ini diimplementasikan dengan menggabungkan API berikut:
- Class
FocusRequester
- Pengubah
focusRequester
- Pengubah
focusRestorer
- Fungsi composable
LaunchedEffect
UX yang diterapkan dapat diuji dengan uji instrumentasi. Compose menawarkan cara untuk melakukan penekanan tombol dan menguji apakah SemanticsNode
memiliki fokus keyboard atau tidak.