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();
}
});
¿Cómo implementar el método isNotSetByUser()
?
Respuestas:
Respuesta 2:
Una respuesta muy simple:
Usar en OnClickListener en lugar de OnCheckedChangeListener
Ahora solo selecciona eventos de clic y no tiene que preocuparse por los cambios programáticos.
Respuesta 1:
He creado una clase contenedora (ver Patrón de decorador) que maneja este problema de forma encapsulada:
CheckBox aún se puede declarar de la misma manera en XML, pero utilícelo al inicializar su GUI en el código:
Si desea establecer marcado desde el código sin activar el oyente, llame en
myCheckBox.silentlySetChecked(someBoolean)
lugar desetChecked
.fuente
Switch
, la respuesta 1 funciona tanto en el caso de toque como en el de diapositiva, mientras que la respuesta 2 solo funcionará en el caso de toque. Como preferencia personal, hice que mi clase se extendieraCheckBox
/ enSwitch
lugar de tener una referencia a una. Se siente más limpio de esa manera (tenga en cuenta que debe especificar el nombre completo del paquete en el XML si lo hace).listener
amyListener
siemprelistener
que no sea nulo. En casi todos los casos esto no hace nada, pero si hacemos un nuevo oyente por alguna razón, eso no está roto.Tal vez puedas comprobar isShown ()? Si es VERDADERO, entonces es usuario. Funciona para mi.
fuente
En el interior,
onCheckedChanged()
solo verifique si el usuario tiene realmentechecked/unchecked
el botón de opción y luego haga las cosas en consecuencia de la siguiente manera:fuente
isPressed
devuelve falso, dispositivo Nokia con TalkBack activado.Puede eliminar el oyente antes de cambiarlo programáticamente y agregarlo nuevamente, como se responde en la siguiente publicación SO:
https://stackoverflow.com/a/14147300/1666070
fuente
Intente extender CheckBox. Algo así (ejemplo no completo):
fuente
Hay otra solución sencilla que funciona bastante bien. El ejemplo es para Switch.
fuente
Interesante pregunta. Que yo sepa, una vez que estás en el oyente, no puedes detectar qué acción ha desencadenado al oyente, el contexto no es suficiente. A menos que utilice un valor booleano externo como indicador.
Cuando marque la casilla "programáticamente", establezca un valor booleano antes para indicar que se hizo mediante programación. Algo como:
Y en su oyente, no olvide restablecer el estado de la casilla de verificación:
fuente
Prueba
NinjaSwitch
:¡Simplemente llame
setChecked(boolean, true)
para cambiar el estado verificado del interruptor sin ser detectado!fuente
Si
OnClickListener
ya está configurado y no debe sobrescribirse, use!buttonView.isPressed()
comoisNotSetByUser()
.De lo contrario, la mejor variante es usar en
OnClickListener
lugar deOnCheckedChangeListener
.fuente
La respuesta aceptada podría simplificarse un poco para no mantener una referencia a la casilla de verificación original. Esto hace que podamos usar
SilentSwitchCompat
(oSilentCheckboxCompat
si lo prefiere) directamente en el XML. También lo hice para que pueda establecer elOnCheckedChangeListener
quenull
si el deseo de hacerlo.Luego puede usar esto directamente en su XML así (Nota: necesitará el nombre completo del paquete):
Luego, puede marcar la casilla en silencio llamando a:
fuente
Aquí está mi implementación
Código Java para conmutador personalizado:
Código Kotlin equivalente:
Para cambiar el estado del interruptor sin activar el uso del oyente:
Puede supervisar el cambio de estado normalmente mediante:
En Kotlin:
fuente
Mi variante con funciones de extensión de Kotlin:
... desafortunadamente tenemos que pasar onCheckedChangeListener cada vez porque la clase CheckBox no tiene getter para el campo mOnCheckedChangeListener ((
Uso:
fuente
Crea una variable
En la aplicación, cuando lo cambie en lugar del usuario, llame
notSetByUser(true)
para que no lo configure el usuario, de lo contrario, llamenotSetByUser(false)
es decir, lo establezca el programa.Por último, en su detector de eventos, después de llamar a isNotSetByUser (), asegúrese de volver a cambiarlo a normal.
Llame a este método siempre que esté manejando esa acción a través del usuario o mediante programación. Llame a notSetByUser () con el valor apropiado.
fuente
Si no se usa la etiqueta de la vista, puede usarla en lugar de extender la casilla de verificación:
cada vez que llame a algo que marque / desmarque la casilla de verificación, también llámelo antes de marcar / desmarcar:
fuente
He creado una extensión con RxJava
PublishSubject
, simple. Reacciona solo en eventos "OnClick".fuente