OnCheckedChanged называется автоматически

У меня есть переключатель в recyclerview, и данные отображаются в recyclerview после извлечения данных из БД. Когда открывается recyclerview, я читаю DB, и если поле в БД "Y", я включаю переключатель, иначе я отключу переключатель. Теперь проблема заключается в том, что также вызывается также прослушиватель onCheckedchanged, я хочу, чтобы onCheckedChanged вызывался, только когда пользователь устанавливает переключатель вручную.

При открытии повторного использования ниже выполняется:

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

Класс ViewHolder:

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, который вызывается, когда recyclerView только что открыт:

@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);
                     }
}

В файле макета:

<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"/>

Ответ 1

Странно, что у всех нас есть эта проблема, но не официальный ответ Google на эту простую проблему.

МОСТ просто проверить:

buttonView.isPressed()

Если true, означает, что пользователь щелкнул представление.

Глобальные переменные не нужны.

Надеюсь, что это поможет.

Ответ 2

Я решил использовать этот подкласс SwitchCompat, чтобы избежать этой проблемы. Таким образом, мне не нужен шаблонный код, где я использую этот класс. Всякий раз, когда вам нужно изменить проверочный код, не запуская слушателя, используйте setCheckedSilent вместо 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 также вызывал прослушивание, когда он установлен в методе onViewCreated, и вы возвращаетесь к предыдущему фрагменту. Надеюсь, это сработает для вас!

Ответ 3

Попробуйте это

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

        if (buttonView.isPressed()) {
          ... //returns true, if user clicks the switch button        
        }}

Ответ 4

Это работает для меня:

 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);
                    }
                }
            });

Ответ 5

используйте глобальную логическую переменную, и при чтении данных из БД задайте значение "true" и после проверки (if) в onCheckChange снова установите "false". в первом методе onCheckChange проверьте, является ли эта переменная ложной, выполняет коды else return (значение по умолчанию для этой переменной должно быть ложным);

@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

Ответ 6

Я столкнулся с той же проблемой внутри экрана ViewPager для фрагментов. Когда мы переключаемся между фрагментами, onCheckedChanged Listener вызывается снова и снова.

Если кто-то еще ищет эту проблему, попробуйте.

@Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            if (buttonView.isInTouchMode()) {
              ... //Your code will come here.         
            }
}