Tengo un switch en un recyclerview y los datos se muestran en la recyclerview después de recuperar los datos de la DB. Cuando el recyclerview se abre leí DB y si un campo en la base de datos es «Y» puedo activar el interruptor o de lo contrario, desactivar el interruptor.
Ahora el problema es que junto con la onCheckedchanged oyente es también llamado, quiero que el onCheckedChanged a ser llamado sólo cuando el usuario ajusta el interruptor manualmente.

En la apertura de la recyclerview a continuación se ejecuta:

holder.enabledisable.setChecked(messengerRecord.get_is_valid().equalsIgnoreCase("Y"));

ViewHolder clase:

public class viewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener{
public SwitchCompat enabledisable;
 public viewHolder(View v) {
            enabledisable = (SwitchCompat) v.findViewById(R.id.enabledisable);
            enabledisable.setOnCheckedChangeListener(this);
...................................
...................................

OncheckedChanged método que se llama cuando el recyclerView se acaba de abrir:

@Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Log.v("ranjith","called oncheckedchanged");
            MessengerRecord rec;
            rec = dbHelper.getRecord(descview.getText().toString());
            switch (buttonView.getId()) {
                case R.id.enabledisable:
                    if (isChecked) {
                        rec.set_is_valid("Y");
                        dbHelper.updateRecord(rec);
                     }
}

En el archivo de Diseño:

<android.support.v7.widget.SwitchCompat
    android:layout_marginRight="16dp"
    android:layout_marginEnd="16dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:focusable="false"
    android:id="@+id/enabledisable"
    android:layout_alignRight="@+id/textview_to"
    android:layout_alignEnd="@+id/textview_to"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"/>
InformationsquelleAutor Psypher | 2014-12-24

6 Comentarios

  1. 218

    Es raro, todos nosotros tenemos este problema, pero no oficial de Google la respuesta a este problema sencillo.

    El MÁS sencillo es comprobar:

    buttonView.isPressed()

    Si es true, significa que el usuario hizo clic en la vista.

    Ninguna de las variables globales es necesario.

    Espero que esto ayude.

    • Se desperdicia muchos días tratando de averiguar por qué onCheckedChanged estaba llamada automáticamente y tirando de mi botón de radio de los estados, lo que significa que mi aplicación inútil. Gracias por señalar a un simple y solución de trabajo que funciona. Por fin puedo pasar a otras cosas importantes en la vida.
    • Este es definitivamente el trabajo. Pero es allí cualquier caso, si el usuario desliza el interruptor? En ese caso, Si la usa se desliza el interruptor, esto no está funcionando.
    • Pulgares para arriba. este es un problema muy común que encontramos en la configuración de parte de casi todas las aplicaciones. Y esta solución es la mejor y más fácil
    • Corrió hacia el problema cuando este se llama en un recyclerview. Cuando el usuario se desplaza por listas largas, onCheckedChanged se llama. Mediante el botón ver isPressed() ayudó. Gracias!
    • Gracias por este sencillo pero gran solución. Esto puede ser usado con RadioButton así. Para RadioGroup, he escrito esta respuesta.
    • Gracias @Surfian por la mención :), me alegro de que esto funciona también para RadioButton
    • la solución no funciona si desliza el Interruptor muy rápidamente. Estúpido De Google
    • no funciona, incluso si usted pasa lentamente.
    • Muy bonito solución! Simple! Actualización de mi aplicación compat biblioteca y funciona bien!
    • Gran solución!
    • La mejor solución !!!!!!
    • Amigo que era la mejor solución hasta la fecha. Muchas gracias por encontrar este defecto.
    • Que hace el trabajo. Tal vez mejorado
    • Gran…de trabajo agradable
    • Imagina todo el desperdicio de horas donde las personas tienen que lidiar con estos alucinante efectos secundarios. Camino para ir a google! Gran respuesta btw
    • trabajó para mí!!! pasó mucho tiempo para que esta solución..
    • Usted puede controlar de forma manual mediante la implementación de OnClickListener y comprobar con el método isChecked() de SwitchCompat, no requieren el uso de onCheckedChangeListener.
    • Encontraste alguna solución?? Esta solución no funciona para mí también.
    • Hola @ShivamPokhriyal. Lo siento, no fue hace mucho tiempo se me olvidaba si tengo una solución o no. Pero ahora no estoy trabajando en Android nada más, soy un desarrollador iOS ahora. 🙂
    • A mí también, a mí también 🙂 me gusta mucho la parte de la creación de la completa interfaz de usuario mediante programación. A pesar de que han encontrado una solución mediante la creación de una matriz de comprobarse la posición y la actualización de la radio del grupo de estatus basado en el valor de la matriz.
    • Gracias por la respuesta correcta.
    • Muchas gracias por la solución, funciona!

  2. 12

    He terminado de usar esta subclase de SwitchCompat para evitar este problema. De esta manera no necesito el código repetitivo en el que estoy usando esta clase.
    Siempre que necesite cambiar la marcada sin disparar el oyente, el uso de setCheckedSilent en lugar de setChecked:

    import android.content.Context;
    import android.os.Parcelable;
    import android.support.v7.widget.SwitchCompat;
    import android.util.AttributeSet;
    
    /**
     * Created by emanuel on 30/5/16.
     */
    public class Switch extends SwitchCompat {
    
        private OnCheckedChangeListener listener;
    
        public Switch(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
            this.listener = listener;
            super.setOnCheckedChangeListener(listener);
        }
    
        @Override
        public void onRestoreInstanceState(Parcelable state) {
            super.setOnCheckedChangeListener(null);
            super.onRestoreInstanceState(state);
            super.setOnCheckedChangeListener(listener);
        }
    
        public void setCheckedSilent(boolean checked) {
            super.setOnCheckedChangeListener(null);
            super.setChecked(checked);
            super.setOnCheckedChangeListener(listener);
        }
    }

    onRestoreInstanceState fue la activación de la escucha también, cuando se establece en la onViewCreated método y se va de nuevo a un fragmento anterior.
    Espero que funcione para usted!

    • Esto está funcionando perfectamente..
  3. 8

    Probar este

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    
            if (buttonView.isPressed()) {
              ... //returns true, if user clicks the switch button        
            }}
  4. 0

    utilizar una variable boolean global y cuando se leen los datos de la DB conjunto es «true», y después de comprobar(si) en onCheckChange conjunto es «falso» de nuevo. en la primera de onCheckChange método de verificación si esta variable es falso ejecutar códigos else return(valor predeterminado de esta variable debe ser false ) ;

    @Override
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
         if(!isSourceDB){ 
    
           Log.v("ranjith","called oncheckedchanged");
            MessengerRecord rec;
            rec = dbHelper.getRecord(descview.getText().toString());
            switch (buttonView.getId()) {
                case R.id.enabledisable:
                    if (isChecked) {
                        rec.set_is_valid("Y");
                        dbHelper.updateRecord(rec);
    
              }
        }//end if
      isSourceDB = false; }//end oncheckedchange
    • Esto parece ser un trabajo a su alrededor. Yo estaba buscando una funcionalidad en android que se llama oncheckedchanged sólo cuando se hace clic por el usuario(i.e enfoque es recevied). Pero funciona. Hasta el voto de mí.
    • cuando el Interruptor pulsado primera toggle() llama al método y en alternar el método de setchecked() llama al método. así que usted debe insertar códigos anteriores en alternar método no en checkchanged. por cierto, si quieres que solo escribir en onCheckChange() usted debe escribir un método que sólo se cambia el estado de la GUI de interruptor y lo llamó cuando se leen los datos de la DB.
  5. 0

    Me enfrentó el mismo problema dentro de la ViewPager pantalla de fragmentos. Cuando se cambia entre los fragmentos, onCheckedChanged Oyente se llama de nuevo y de nuevo.

    Si alguien sigue buscando a este problema, por favor, inténtelo.

    @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    
                if (buttonView.isInTouchMode()) {
                  ... //Your code will come here.         
                }
    }
    • Voy a probar y te permiten saber si funciona para mí
    • No trabajo para mí, pero buttonView.isPressed() no.
  6. 0

    Esto funciona para mí:

        <pre> 
    
    
     boolean selected = preferences.isChecked();
            yourCheckBox.setOnCheckedChangeListener(new 
                CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, 
                boolean isChecked) {
                        if (buttonView.isPressed()) {
                   preferences.setChecked(isChecked);
                        } else {
                            yourCheckBox.setChecked(selected);
                        }
                    }
                });
        <code>

Dejar respuesta

Please enter your comment!
Please enter your name here