setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// How to check whether the checkbox/switch has been checked
// by user or it has been checked programatically ?
if (isNotSetByUser())
return;
handleSetbyUser();
}
});
Bagaimana cara menerapkan metode isNotSetByUser()
?
Jawaban:
Jawaban 2:
Jawaban yang sangat sederhana:
Gunakan di OnClickListener, bukan OnCheckedChangeListener
Sekarang Anda hanya mengambil peristiwa klik dan tidak perlu khawatir tentang perubahan terprogram.
Jawaban 1:
Saya telah membuat kelas pembungkus (lihat Pola Dekorator) yang menangani masalah ini dengan cara yang dikemas:
Kotak Centang masih dapat dinyatakan sama dalam XML, tetapi gunakan ini saat menginisialisasi GUI Anda dalam kode:
Jika Anda ingin menyetel diperiksa dari kode tanpa memicu pemroses, panggil
myCheckBox.silentlySetChecked(someBoolean)
sajasetChecked
.sumber
Switch
, jawaban 1 berfungsi di kotak ketuk dan geser, sedangkan jawaban 2 hanya akan berfungsi di kotak ketuk. Sebagai preferensi pribadi, saya membuat kelas saya diperpanjangCheckBox
/Switch
daripada memegang referensi ke salah satunya. Terasa lebih bersih seperti itu (perhatikan bahwa Anda harus menentukan nama paket lengkap di XML jika Anda melakukannya).listener
untukmyListener
setiap kalilistener
tidak null. Dalam hampir semua kasus ini tidak melakukan apa-apa, tetapi jika kita membuat pendengar baru karena suatu alasan, itu tidak rusak.Mungkin Anda dapat memeriksa isShown ()? Jika BENAR - daripada pengguna itu. Bekerja untuk saya.
sumber
Di dalam,
onCheckedChanged()
periksa saja apakah pengguna benarchecked/unchecked
- benar memiliki tombol radio dan kemudian lakukan hal-hal yang sesuai sebagai berikut:sumber
isPressed
pengembalian palsu, perangkat Nokia dengan TalkBack aktif.Anda dapat menghapus pendengar sebelum mengubahnya secara terprogram dan menambahkannya lagi, seperti yang dijawab di posting SO berikut:
https://stackoverflow.com/a/14147300/1666070
sumber
Coba perluas Kotak Centang. Sesuatu seperti itu (bukan contoh lengkap):
sumber
Ada solusi sederhana lain yang berfungsi dengan baik. Contohnya adalah untuk Switch.
sumber
Pertanyaan menarik. Sepengetahuan saya, setelah Anda menjadi pendengar, Anda tidak dapat mendeteksi tindakan apa yang telah memicu pendengar, konteksnya saja tidak cukup. Kecuali Anda menggunakan nilai boolean eksternal sebagai indikator.
Jika Anda mencentang kotak "secara terprogram", setel nilai boolean sebelumnya untuk menunjukkan bahwa itu dilakukan secara terprogram. Sesuatu seperti:
Dan di listener Anda, jangan lupa untuk mengatur ulang status kotak centang:
sumber
Coba
NinjaSwitch
:Panggil saja
setChecked(boolean, true)
untuk mengubah status centang sakelar tanpa terdeteksi!sumber
Jika
OnClickListener
sudah disetel dan tidak boleh ditimpa, gunakan!buttonView.isPressed()
sebagaiisNotSetByUser()
.Jika tidak varian terbaik adalah dengan menggunakan
OnClickListener
bukanOnCheckedChangeListener
.sumber
Jawaban yang diterima dapat disederhanakan sedikit untuk tidak mempertahankan referensi ke kotak centang asli. Ini membuatnya jadi kita bisa menggunakan
SilentSwitchCompat
(atauSilentCheckboxCompat
jika Anda lebih suka) langsung di XML. Saya juga membuatnya sehingga Anda dapat menyetelOnCheckedChangeListener
kenull
jika Anda ingin melakukannya.Anda kemudian dapat menggunakan ini secara langsung di XML Anda seperti itu (Catatan: Anda akan membutuhkan nama paket secara keseluruhan):
Kemudian Anda dapat mencentang kotak secara diam-diam dengan menelepon:
sumber
Inilah implementasi saya
Kode Java untuk Custom Switch:
Kode Kotlin yang Setara:
Untuk mengubah status sakelar tanpa memicu penggunaan pemroses:
Anda dapat memantau perubahan status seperti biasa dengan:
Di Kotlin:
sumber
Varian saya dengan fungsi ekstensi Kotlin:
... sayangnya kita perlu meneruskan onCheckedChangeListener setiap saat karena kelas CheckBox tidak mendapatkan bidang mOnCheckedChangeListener ((
Pemakaian:
sumber
Buat variabel
Dalam aplikasi ketika Anda mengubahnya, bukan pengguna, panggil
notSetByUser(true)
jadi itu tidak diatur oleh pengguna, jika tidak panggilnotSetByUser(false)
misalnya itu diatur oleh program.Terakhir, di event listener Anda, setelah memanggil isNotSetByUser (), pastikan Anda mengubahnya kembali ke normal.
Panggil metode ini setiap kali Anda menangani tindakan itu baik melalui pengguna atau secara terprogram. Panggil notSetByUser () dengan nilai yang sesuai.
sumber
Jika tag tampilan tidak digunakan, Anda dapat menggunakannya sebagai ganti memperluas kotak centang:
setiap kali Anda memanggil sesuatu yang mencentang / tidak mencentang kotak centang, panggil juga ini sebelum mencentang / menghapus centang:
sumber
Saya telah membuat ekstensi dengan RxJava
PublishSubject
, yang sederhana. Bereaksi hanya pada acara "OnClick".sumber