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();
}
});
Wie implementiere ich eine Methode isNotSetByUser()
?
Antworten:
Antwort 2:
Eine sehr einfache Antwort:
Verwenden Sie OnClickListener anstelle von OnCheckedChangeListener
Jetzt erfassen Sie nur noch Klickereignisse und müssen sich nicht mehr um programmatische Änderungen kümmern.
Antwort 1:
Ich habe eine Wrapper-Klasse erstellt (siehe Decorator-Muster), die dieses Problem gekapselt behandelt:
CheckBox kann in XML weiterhin als gleich deklariert werden. Verwenden Sie dies jedoch, wenn Sie Ihre GUI im Code initialisieren:
Wenn Sie Checked from Code festlegen möchten, ohne den Listener auszulösen, rufen Sie
myCheckBox.silentlySetChecked(someBoolean)
stattdessen stattsetChecked
.quelle
Switch
funktioniert Antwort 1 sowohl in Tap- als auch in Slide-Fällen, während Antwort 2 nur in Tap-Fällen funktioniert. Als persönliche Präferenz habe ich meine Klasse erweitertCheckBox
/Switch
anstatt einen Verweis auf eine zu halten. Fühlt sich auf diese Weise sauberer an (beachten Sie, dass Sie den vollständigen Paketnamen im XML angeben müssen, wenn Sie dies tun).listener
zu,myListener
wannlistener
immer nicht null ist. In fast allen Fällen tut dies nichts, aber wenn wir aus irgendeinem Grund einen neuen Hörer erstellen, ist das nicht kaputt.Vielleicht können Sie isShown () überprüfen? Wenn WAHR - dann ist es Benutzer. Funktioniert bei mir.
quelle
onCheckedChanged()
Überprüfen Sie in der Datei, ob der Benutzer tatsächlichchecked/unchecked
das Optionsfeld hat, und führen Sie die entsprechenden Schritte aus:quelle
isPressed
falsches Nokia-Gerät mit aktiviertem TalkBack zurückgegeben.Sie können den Listener entfernen, bevor Sie ihn programmgesteuert ändern, und ihn erneut hinzufügen, wie im folgenden SO-Beitrag beantwortet:
https://stackoverflow.com/a/14147300/1666070
quelle
Versuchen Sie, CheckBox zu erweitern. So etwas (nicht vollständiges Beispiel):
quelle
Es gibt eine andere einfache Lösung, die ziemlich gut funktioniert. Beispiel ist für Switch.
quelle
Interessante Frage. Meines Wissens können Sie im Listener nicht erkennen, welche Aktion den Listener ausgelöst hat. Der Kontext reicht nicht aus. Es sei denn, Sie verwenden einen externen booleschen Wert als Indikator.
Wenn Sie das Kontrollkästchen "programmgesteuert" aktivieren, legen Sie zuvor einen booleschen Wert fest, um anzuzeigen, dass er programmgesteuert ausgeführt wurde. Etwas wie:
Vergessen Sie in Ihrem Listener nicht, den Status des Kontrollkästchens zurückzusetzen:
quelle
Versuchen Sie
NinjaSwitch
:Rufen Sie einfach
setChecked(boolean, true)
an, um den geprüften Status des Schalters zu ändern, ohne ihn zu erkennen!quelle
Wenn
OnClickListener
bereits festgelegt und nicht überschrieben werden soll, verwenden Sie!buttonView.isPressed()
alsisNotSetByUser()
.Ansonsten ist die beste Variante verwenden
OnClickListener
stattOnCheckedChangeListener
.quelle
Die akzeptierte Antwort könnte etwas vereinfacht werden, um keinen Verweis auf das ursprüngliche Kontrollkästchen beizubehalten. Dies macht es so, dass wir das
SilentSwitchCompat
(oderSilentCheckboxCompat
wenn Sie es vorziehen) direkt im XML verwenden können. Ich habe es auch so gemacht, dass Sie das einstellen könnenOnCheckedChangeListener
,null
wenn Sie dies wünschen.Sie können dies dann direkt in Ihrem XML verwenden (Hinweis: Sie benötigen den gesamten Paketnamen):
Dann können Sie das Kontrollkästchen stillschweigend aktivieren, indem Sie Folgendes anrufen:
quelle
Hier ist meine Implementierung
Java-Code für benutzerdefinierten Switch:
Äquivalenter Kotlin-Code:
Um den Schaltzustand zu ändern, ohne den Listener auszulösen, verwenden Sie:
Sie können die Statusänderung wie gewohnt überwachen, indem Sie:
In Kotlin:
quelle
Meine Variante mit Kotlin-Erweiterungsfunktionen:
... leider müssen wirCheckedChangeListener jedes Mal weitergeben, da die CheckBox-Klasse keinen Getter für das Feld mOnCheckedChangeListener hat (()
Verwendung:
quelle
Erstellen Sie eine Variable
Wenn Sie es in der Anwendung anstelle des Benutzers ändern, rufen Sie es auf,
notSetByUser(true)
damit es nicht vom Benutzer festgelegt wird, andernfalls rufennotSetByUser(false)
Sie es auf, dh es wird vom Programm festgelegt.Stellen Sie in Ihrem Ereignis-Listener nach dem Aufruf von isNotSetByUser () sicher, dass Sie ihn wieder auf normal zurücksetzen.
Rufen Sie diese Methode auf, wenn Sie diese Aktion entweder über den Benutzer oder programmgesteuert ausführen. Rufen Sie notSetByUser () mit dem entsprechenden Wert auf.
quelle
Wenn das Tag der Ansicht nicht verwendet wird, können Sie es verwenden, anstatt das Kontrollkästchen zu erweitern:
Rufen Sie dies jedes Mal auf, wenn Sie etwas aufrufen, das das Kontrollkästchen aktiviert / deaktiviert, bevor Sie das Kontrollkästchen aktivieren / deaktivieren:
quelle
Ich habe eine
PublishSubject
einfache Erweiterung mit RxJava erstellt . Reagiert nur auf "OnClick" -Ereignisse.quelle