Checkbox & Switch
Input boolean: Checkbox, Switch, dan SwitchListTile.
Kenapa Ada Checkbox & Switch?
Hampir semua aplikasi butuh jawaban ya atau tidak dari user: setuju dengan syarat layanan, aktifkan notifikasi, tampilkan password. Kamu bisa saja memakai tombol biasa, tapi user harus menebak statusnya dari teks. Checkbox dan Switch menyelesaikan masalah itu dengan bahasa visual yang langsung terbaca: tercentang berarti ya, tergeser berarti aktif.
Keduanya memang sama-sama boolean, tapi maknanya beda. Checkbox berkata "pilih item ini", cocok untuk checklist dan persetujuan. Switch berkata "nyalakan atau matikan sesuatu", cocok untuk pengaturan yang langsung berefek. Salah pilih bikin user bingung: checkbox untuk dark mode terasa aneh, dan switch untuk "saya setuju" juga janggal.
Contoh Dasar
Contoh paling sederhana: satu state boolean yang dibaca dua widget sekaligus.
bool _setuju = false;
Checkbox(
value: _setuju,
onChanged: (nilai) => setState(() => _setuju = nilai ?? false),
)
Switch(
value: _setuju,
onChanged: (nilai) => setState(() => _setuju = nilai),
)Perhatikan perbedaan kecil tapi penting: onChanged milik Checkbox menerima bool? (nullable), sedangkan Switch menerima bool. Ini karena Checkbox mendukung mode tristate yang dibahas di bawah. Untuk form biasa, pola nilai ?? false adalah cara paling aman agar null-safety tidak protes.
Tile Siap Pakai: Label Sekalian
Checkbox dan Switch polos tidak punya label, jadi kamu harus menyusun Row manual dengan Text. Versi ListTile menyelesaikan itu: area sentuh lebih besar, label dan subtitle rapi, dan seluruh baris bisa diklik.
bool _notifPromo = true;
bool _setuju = false;
// di dalam build:
SwitchListTile(
title: const Text('Notifikasi promo'),
subtitle: const Text('Dapatkan info diskon terbaru'),
secondary: const Icon(Icons.local_offer),
value: _notifPromo,
onChanged: (v) => setState(() => _notifPromo = v),
),
CheckboxListTile(
title: const Text('Saya setuju dengan syarat & ketentuan'),
value: _setuju,
controlAffinity: ListTileControlAffinity.leading,
onChanged: (v) => setState(() => _setuju = v ?? false),
),
const Divider(),
ElevatedButton(
onPressed: _setuju ? _kirimFormulir : null,
child: const Text('Daftar'),
),Pola terakhir itu contoh nyata: tombol Daftar aktif hanya jika checkbox dicentang. Ini validasi paling sederhana untuk form persetujuan.
Tristate: Nilai Ketiga Bernilai Null
Secara default Checkbox hanya kenal true dan false. Dengan tristate: true, ia punya tiga status: true, false, dan null yang tampil sebagai strip minus. Kegunaan klasiknya adalah pola "pilih semua":
bool? _semua = false; // null berarti "sebagian terpilih"
Checkbox(
tristate: true,
value: _semua,
onChanged: (v) => setState(() {
_semua = v;
_itemA = _itemB = _itemC = (v ?? false);
}),
),Saat sebagian item dicentang manual, set _semua = null agar tampil strip minus, pola standar di daftar tugas.
Edge Case & Best Practice
Pertama, Switch sebaiknya langsung berefek begitu digeser. Kalau perubahan butuh tombol Simpan terpisah, Checkbox lebih jujur secara visual. Kedua, jangan memakai Switch untuk aksi destruktif (mis. hapus akun) tanpa dialog konfirmasi, karena geserannya terlalu mudah dan tidak bisa di-undo. Ketiga, untuk daftar pengaturan yang panjang, selalu pakai SwitchListTile, bukan Switch polos, karena area sentuhnya memenuhi standar aksesibilitas 48px.
Keempat, hati-hati dengan state yang datang terlambat, mis. dari API. Tampilkan loading atau nilai default dulu, jangan biarkan Switch berkedip setelah data tiba. Kelima, buat title tile deskriptif agar pembaca layar mengumumkannya dengan jelas.
Kapan TIDAK Memakai Ini
Jangan pakai Checkbox atau Switch untuk memilih satu dari banyak opsi, itu tugas Radio atau SegmentedButton. Jangan pakai Switch untuk memilih banyak dari banyak opsi, itu tugas Checkbox biasa. Kalau opsinya lebih dari tujuh, Dropdown atau halaman pilihan tersendiri lebih rapi daripada deretan switch yang tak berujung. Dan jangan memakai checkbox sebagai tombol aksi, karena user membacanya sebagai status, bukan perintah.
Catatan teknis:
onChanged: nullmembuat widget dalam keadaan disabled (abu-abu dan tidak bisa disentuh). Ini cara resmi menonaktifkan Checkbox/Switch tanpa membungkusnya dengan IgnorePointer.
Tantangan
Pengaturan notifikasi
Buat halaman pengaturan dengan 3 SwitchListTile: 'Promo', 'Pesanan', 'Berita'. Tambahkan teks di bawah yang menampilkan jumlah yang aktif.