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();
}
});
Comment mettre en œuvre la méthode isNotSetByUser()
?
Réponses:
Réponse 2:
Une réponse très simple:
Utiliser sur OnClickListener au lieu de OnCheckedChangeListener
Désormais, vous ne récupérez que les événements de clic et vous n'avez pas à vous soucier des modifications programmatiques.
Réponse 1:
J'ai créé une classe wrapper (voir Decorator Pattern) qui gère ce problème de manière encapsulée:
CheckBox peut toujours être déclaré de la même manière en XML, mais utilisez ceci lors de l'initialisation de votre interface graphique dans le code:
Si vous souhaitez définir vérifié à partir du code sans déclencher l'écouteur, appelez à la
myCheckBox.silentlySetChecked(someBoolean)
place desetChecked
.la source
Switch
, la réponse 1 fonctionne à la fois dans les cas du robinet et de la diapositive, tandis que la réponse 2 ne fonctionnera que dans le cas du robinet. Par préférence personnelle, j'ai demandé à ma classe d'étendreCheckBox
/Switch
plutôt que de tenir une référence à une. Cela semble plus propre (notez que vous devez spécifier le nom complet du package dans le XML si vous faites cela).listener
àmyListener
chaque foislistener
n'est pas nul. Dans presque tous les cas, cela ne fait rien, mais si nous créons un nouvel auditeur pour une raison quelconque, ce n'est pas cassé.Peut-être pouvez-vous vérifier isShown ()? Si TRUE - que c'est l'utilisateur. Travaille pour moi.
la source
À l'intérieur,
onCheckedChanged()
vérifiez simplement si l'utilisateur a réellementchecked/unchecked
le bouton radio, puis faites les choses en conséquence comme suit:la source
isPressed
renvoie faux, appareil Nokia avec TalkBack activé.Vous pouvez supprimer l'écouteur avant de le modifier par programme et l'ajouter à nouveau, comme indiqué dans le message SO suivant:
https://stackoverflow.com/a/14147300/1666070
la source
Essayez d'étendre CheckBox. Quelque chose comme ça (exemple incomplet):
la source
Il existe une autre solution simple qui fonctionne plutôt bien. L'exemple est pour Switch.
la source
Question interessante. À ma connaissance, une fois que vous êtes dans l'auditeur, vous ne pouvez pas détecter quelle action a déclenché l'auditeur, le contexte ne suffit pas. Sauf si vous utilisez une valeur booléenne externe comme indicateur.
Lorsque vous cochez la case «par programme», définissez une valeur booléenne avant d'indiquer qu'il a été effectué par programme. Quelque chose comme:
Et dans votre auditeur, n'oubliez pas de réinitialiser l'état de la case à cocher:
la source
Essayez
NinjaSwitch
:Appelez simplement
setChecked(boolean, true)
pour changer l'état vérifié du commutateur sans détection!la source
Si
OnClickListener
est déjà défini et ne doit pas être écrasé, utilisez!buttonView.isPressed()
asisNotSetByUser()
.Sinon, la meilleure variante est d'utiliser à la
OnClickListener
place deOnCheckedChangeListener
.la source
La réponse acceptée pourrait être un peu simplifiée pour ne pas conserver une référence à la case d'origine. Cela nous permet d'utiliser le
SilentSwitchCompat
(ouSilentCheckboxCompat
si vous préférez) directement dans le XML. Je l'ai également fait pour que vous puissiez définir leOnCheckedChangeListener
surnull
si vous le souhaitez.Vous pouvez ensuite l'utiliser directement dans votre XML comme ceci (Remarque: vous aurez besoin du nom complet du package):
Ensuite, vous pouvez cocher la case en silence en appelant:
la source
Voici ma mise en œuvre
Code Java pour le commutateur personnalisé:
Code Kotlin équivalent:
Pour changer l'état du commutateur sans déclencher l'écouteur, utilisez:
Vous pouvez surveiller le changement d'état normalement en:
À Kotlin:
la source
Ma variante avec les fonctions d'extension Kotlin:
... malheureusement, nous devons passer onCheckedChangeListener à chaque fois car la classe CheckBox n'a pas de getter pour le champ mOnCheckedChangeListener ((
Usage:
la source
Créer une variable
Dans l'application lorsque vous le modifiez à la place de l'utilisateur, appelez
notSetByUser(true)
pour qu'il ne soit pas défini par l'utilisateur, sinon appeleznotSetByUser(false)
c'est-à - dire qu'il est défini par programme.Enfin, dans votre écouteur d'événements, après avoir appelé isNotSetByUser (), assurez-vous de le remettre à nouveau à la normale.
Appelez cette méthode chaque fois que vous gérez cette action via l'utilisateur ou par programme. Appelez notSetByUser () avec la valeur appropriée.
la source
Si la balise de la vue n'est pas utilisée, vous pouvez l'utiliser au lieu d'étendre la case à cocher:
chaque fois que vous appelez quelque chose qui coche / décoche la case, appelez également ceci avant de cocher / décocher:
la source
J'ai créé une extension avec RxJava
PublishSubject
, simple. Réagit uniquement sur les événements "OnClick".la source