Tombol ikon

Tombol ikon menampilkan tindakan yang dapat dilakukan pengguna. Tombol ikon harus menggunakan ikon dengan makna yang jelas, dan biasanya mewakili tindakan umum atau yang sering digunakan.

Ada dua jenis tombol ikon:

  • Default: Tombol ini dapat membuka elemen lain, seperti menu atau penelusuran.
  • Tombol: Tombol ini dapat mewakili tindakan biner yang dapat diaktifkan atau dinonaktifkan, seperti "favorit" atau "bookmark".
5 tombol ikon dengan ikon yang berbeda (setelan, lainnya, dll.). Beberapa diisi, yang menunjukkan pilihan, dan beberapa diuraikan.
Gambar 1. Tombol ikon, beberapa di antaranya terisi (menunjukkan pilihan) dan bergaris batas.

Platform API

Gunakan composable IconButton untuk menerapkan tombol ikon standar. Untuk membuat gaya visual yang berbeda seperti terisi, tonal terisi, atau bergaris batas, gunakan FilledIconButton, FilledTonalIconButton, dan OutlinedIconButton.

Parameter utama untuk IconButton meliputi:

  • onClick: Fungsi lambda yang dijalankan saat pengguna mengetuk tombol ikon.
  • enabled: Boolean yang mengontrol status aktif tombol. Jika false, tombol tidak merespons input pengguna.
  • content: Konten composable di dalam tombol, biasanya Icon.

Contoh dasar: Tombol ikon beralih

Contoh ini menunjukkan cara menerapkan tombol ikon tombol. Tombol ikon tombol beralih mengubah tampilannya berdasarkan apakah tombol tersebut dipilih atau tidak dipilih.

@Preview
@Composable
fun ToggleIconButtonExample() {
    // isToggled initial value should be read from a view model or persistent storage.
    var isToggled by rememberSaveable { mutableStateOf(false) }

    IconButton(
        onClick = { isToggled = !isToggled }
    ) {
        Icon(
            painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite),
            contentDescription = if (isToggled) "Selected icon button" else "Unselected icon button."
        )
    }
}

Poin penting tentang kode

  • Composable ToggleIconButtonExample menentukan IconButton yang dapat diubah.
    • mutableStateOf(false) membuat objek MutableState yang menyimpan nilai boolean, yang awalnya false. Hal ini menjadikan isToggled sebagai holder status, yang berarti Compose merekomposisi UI setiap kali nilainya berubah.
    • rememberSaveable memastikan status isToggled tetap ada di seluruh perubahan konfigurasi, seperti rotasi layar.
  • Lambda onClick dari IconButton menentukan perilaku tombol saat diklik, yang mengalihkan status antara true dan false.
  • Parameter painter composable Icon secara bersyarat memuat painterResource yang berbeda berdasarkan status isToggled. Tindakan ini akan mengubah tampilan visual ikon.
    • Jika isToggled adalah true, kode akan memuat drawable hati yang terisi.
    • Jika isToggled adalah false, drawable hati yang digariskan akan dimuat.
  • contentDescription dari Icon juga diperbarui berdasarkan status isToggled untuk memberikan informasi aksesibilitas yang sesuai.

Hasil

Gambar berikut menunjukkan tombol ikon tombol dari cuplikan sebelumnya dalam status tidak dipilih:

Tombol ikon beralih favorit (hati) dalam status tidak dipilih (tidak terisi).
Gambar 2. Tombol ikon tombol "favorit" dalam status tidak dipilih.

Contoh lanjutan: Tindakan berulang saat ditekan

Bagian ini menunjukkan cara membuat tombol ikon yang terus memicu tindakan saat pengguna menekan dan menahannya, bukan hanya memicu sekali per klik.

@Composable
fun MomentaryIconButton(
    unselectedImage: Int,
    selectedImage: Int,
    contentDescription: String,
    modifier: Modifier = Modifier,
    stepDelay: Long = 100L, // Minimum value is 1L milliseconds.
    onClick: () -> Unit
) {
    val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()
    val pressedListener by rememberUpdatedState(onClick)

    LaunchedEffect(isPressed) {
        while (isPressed) {
            delay(stepDelay.coerceIn(1L, Long.MAX_VALUE))
            pressedListener()
        }
    }

    IconButton(
        modifier = modifier,
        onClick = onClick,
        interactionSource = interactionSource
    ) {
        Icon(
            painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage),
            contentDescription = contentDescription,
        )
    }
}

Poin penting tentang kode

  • MomentaryIconButton menggunakan unselectedImage: Int, ID resource drawable untuk ikon saat tombol tidak ditekan, dan selectedImage: Int, ID resource drawable untuk ikon saat tombol ditekan.
  • Class ini menggunakan interactionSource untuk melacak interaksi "tekan" secara khusus dari pengguna.
  • isPressed bernilai benar (true) saat tombol sedang ditekan secara aktif dan salah (false) jika tidak. Jika isPressed adalah true, LaunchedEffect akan memasuki loop.
    • Di dalam loop ini, skrip menggunakan delay (dengan stepDelay) untuk membuat jeda di antara tindakan pemicu. coerceIn memastikan penundaan minimal 1 md untuk mencegah loop tanpa batas.
    • pressedListener dipanggil setelah setiap penundaan dalam loop. Tindakan ini membuat tindakan berulang.
  • pressedListener menggunakan rememberUpdatedState untuk memastikan bahwa lambda onClick (tindakan yang akan dilakukan) selalu yang terbaru dari komposisi terbaru.
  • Icon mengubah gambar yang ditampilkan berdasarkan apakah tombol sedang ditekan atau tidak.
    • Jika isPressed benar, selectedImage akan ditampilkan.
    • Jika tidak, unselectedImage akan ditampilkan.

Selanjutnya, gunakan MomentaryIconButton ini dalam contoh. Cuplikan berikut menunjukkan dua tombol ikon yang mengontrol penghitung:

@Preview()
@Composable
fun MomentaryIconButtonExample() {
    var pressedCount by remember { mutableIntStateOf(0) }

    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically
    ) {
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_rewind,
            selectedImage = R.drawable.fast_rewind_filled,
            stepDelay = 100L,
            onClick = { pressedCount -= 1 },
            contentDescription = "Decrease count button"
        )
        Spacer(modifier = Modifier)
        Text("advanced by $pressedCount frames")
        Spacer(modifier = Modifier)
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_forward,
            selectedImage = R.drawable.fast_forward_filled,
            contentDescription = "Increase count button",
            stepDelay = 100L,
            onClick = { pressedCount += 1 }
        )
    }
}

Poin penting tentang kode

  • Composable MomentaryIconButtonExample menampilkan Row yang berisi dua instance MomentaryIconButton dan composable Text untuk membuat UI yang menambah dan mengurangi penghitung.
  • Fungsi ini mempertahankan variabel status pressedCount yang dapat diubah menggunakan remember dan mutableIntStateOf, yang diinisialisasi ke 0. Saat pressedCount berubah, composable apa pun yang mengamatinya (seperti composable Text) akan merekomposisi untuk mencerminkan nilai baru.
  • MomentaryIconButton pertama mengurangi pressedCount saat diklik atau ditahan.
  • MomentaryIconButton kedua meningkatkan pressedCount saat diklik atau ditahan.
  • Kedua tombol menggunakan stepDelay 100 milidetik, yang berarti tindakan onClick diulang setiap 100 milidetik saat tombol ditekan.

Hasil

Video berikut menunjukkan UI dengan tombol ikon dan penghitung:

Gambar 3. UI penghitung dengan dua tombol ikon (plus dan minus) yang menambah dan mengurangi penghitung.

Referensi lainnya