Android - программно изменить состояние переключателя без запуска слушателя OnCheckChanged


Я ищу метод программного изменения состояния виджета Android Switch с помощью switch.setChecked(true); без запуска OnCheckedChangedlistener.

Моей первой мыслью было заменить его на OnClickListener, но так как он регистрирует только клики, и вы можете не только нажимать, но и двигать переключатель, то он не совсем подходит для этой цели, как если бы пользователь скользил Переключатель с выключенного на включенный, тогда переключатель фактически ничего не делает, поскольку пользователь не нажимает...

Если у кого-то есть решение или умный обходной путь для этого, это было бы здорово


person Paul Alexander    schedule 03.09.2014    source источник
comment
Пожалуйста, используйте приведенную ниже строку кода. кнопкаView.isPressed()   -  person Mandeep Yadav    schedule 05.03.2019


Ответы (9)


Ну, прямо перед тем, как делать что-то в коде с помощью переключателя, вы можете просто отменить регистрацию прослушивателя, затем сделать все, что вам нужно, и снова зарегистрировать прослушиватель.

person smnpl    schedule 03.09.2014
comment
Как бы вы отменили регистрацию слушателя? извините, я совсем новичок в этом - person Paul Alexander; 03.09.2014
comment
Я думаю, что есть два варианта: 1. switch.setOnCheckedChangeListener(null); //хотя не уверен, может ли это привести к проблемам... 2. создать фиктивный класс, реализующий OnCheckedChangeListender с фиктивным методом onCheckedChanged, который ничего не делает. затем зарегистрировать новый объект этого, а затем снова зарегистрировать слушателя по умолчанию - person smnpl; 03.09.2014
comment
поэтому, если бы я использовал switch.setOnCheckedChangeListener(null); как мне тогда перерегистрировать слушателя? это будет switch.setOnCheckedChangeListener(listener);?? - person Paul Alexander; 03.09.2014
comment
Пока «слушатель» является ссылкой на ваш объект слушателя, да. Это был бы мой подход к решению этой проблемы (хотя есть и лучшие решения). - person smnpl; 03.09.2014
comment
хм, похоже, я не могу заставить перерегистрацию работать... Я не уверен, что я должен помещать в скобки switch.setOnCheckedChangeListener(); - person Paul Alexander; 03.09.2014
comment
а, не беспокойтесь, понял! - person Paul Alexander; 03.09.2014
comment
Спасибо за помощь, отличное решение! - person Paul Alexander; 03.09.2014
comment
Как вы перерегистрировали слушателя? - person vamsidhar muthireddy; 02.04.2017

Установите прослушиватель на null перед вызовом функции setCheck() и включите его после этого, например:

switch.setOnCheckedChangeListener (null);
switch.setChecked(true);
switch.setOnCheckedChangeListener (this);

Справка: изменение значения флажка без срабатывания onCheckChanged

person Mahmoud Ibrahim    schedule 18.07.2016
comment
Извините, но это не сработало, onCheckedChanged все еще неоднократно вызывался. - person iCantC; 16.04.2020

Каждая CompoundButton (кнопка с двумя состояниями — вкл./выкл.) нажата состояние, которое истинно только когда пользователь нажимает на представление.

Просто добавьте проверку в свой слушатель перед запуском фактической логики:

if(compoundButton.isPressed()) {
    // continue with your listener
}

Таким образом, программное изменение проверенного значения не приведет к запуску нежелательного кода.

Из ответа @krisDrOid.

person ronginat    schedule 11.04.2019
comment
Это не работает надежно, так как isPressed часто будет ложным для взаимодействия с переключателем, а не касанием. - person Roman Kotenko; 11.02.2021

У меня есть одно решение, и оно отлично работает на моем конце. Я добавил setOnTouchListener и setOnCheckedChangeListener в свой элемент управления переключателем и добавил следующий код для решения моей проблемы.

    // set tag by default.
    mMySwitch.setTag("TAG");

    // Add OnCheckedChangeListener.
    mMySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
         @Override
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (mMySwitch.getTag() != null) {
                 mMySwitch.setTag(null);
                 return;
                }

          // Do your stuff here.
        }
    });

    // Add Touch listener.
    mMySwitch.setOnTouchListener(new View.OnTouchListener() {
         @Override
         public boolean onTouch(View v, MotionEvent event) {
            mMySwitch.setTag(null);
            return false;
         }
    });

Таким образом, setOnCheckedChangeListener вызывается только тогда, когда изменение проверки происходит в результате вмешательства человека путем перетаскивания, щелчка, прикосновения.

Также не забудьте добавить свой действительный строковый тег (не null), когда вы пытаетесь изменить статус проверки переключателя. подобно :

 mMySwitch.setTag("TAG");
 mMySwitch.setChecked(true);
person Chetan Bhoyar    schedule 28.09.2015
comment
Спасибо за это решение, мне очень помогло!! нет необходимости в mListener, к сожалению, нет метода switch.getOnCheckedChangeListener(). Кстати: в вашем onCheckedChanged() можно заменить mMySwitch на buttonView - person Lucker10; 23.07.2016

Напишите собственный Switch или SwitchCompat и переопределите setOnCheckedListener.

public class SwitchCompat extends android.support.v7.widget.SwitchCompat {
private boolean mIgnoreCheckedChange = false;

public SwitchCompat(Context context) {
    super(context);
}

public SwitchCompat(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public SwitchCompat(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}


@Override
public void setOnCheckedChangeListener(final OnCheckedChangeListener listener) {
    super.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (mIgnoreCheckedChange) {
                return;
            }
            listener.onCheckedChanged(buttonView, isChecked);
        }
    });
}

public void setChecked(boolean checked, boolean notify) {
    mIgnoreCheckedChange = !notify;
    setChecked(checked);
    mIgnoreCheckedChange = false;
}

}
person hyb1996    schedule 18.09.2017
comment
Отлично работаете, гениально! - person Houssem; 17.01.2018

лучшее решение, которое я могу найти, это;

const val SWITCH_COMPAT_IGNORE_TAG = "SWITCH_COMPAT_IGNORE_TAG"

fun SwitchCompat.isCheckedWithIgnoreTag(isChecked: Boolean) {
    tag = SWITCH_COMPAT_IGNORE_TAG
    this.isChecked = isChecked
    tag = null
}

switchCompat.isCheckedWithIgnoreTag(true)

switchCompat.setOnCheckedChangeListener { buttonView, isChecked ->
    if (buttonView.tag != SWITCH_COMPAT_IGNORE_TAG) {
        //TODO
    }
}
person Cafer Mert Ceyhan    schedule 22.02.2021

используйте этот switch.setChecked(true); // first set value (from pref or server or anywhere) and than switch.setOnCheckedChangeListener (this); добавить слушателя.

person nilesh prajapati    schedule 18.07.2020

Если ничего не сработало, это сложное решение.

Создайте текстовое представление поверх переключателя и добавьте clickListener в текстовое представление.

 <TextView
        android:elevation="1dp"
        android:id="@+id/switchLabel"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text=""
        app:layout_constraintBottom_toBottomOf="@id/switch1"
        app:layout_constraintStart_toStartOf="@+id/switch1"
        app:layout_constraintTop_toTopOf="@id/switch1"
        app:layout_constraintEnd_toEndOf="@id/switch1" />

Добавьте возвышение в текстовое представление.

person Athira    schedule 15.03.2021

Разработка ответа Махмуда

CompoundButton.OnCheckedChangeListener switchListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    switchListener = new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                //Implement on check change
            }
        }; 
      switch.setOnCheckedChangeListener (switchListener);

      //When you want to trigger the checked of switch do the following
      switch.setOnCheckedChangeListener (null);
      switch.setChecked(true);
      switch.setOnCheckedChangeListener (switchListener);
     }

`

person Ismail Iqbal    schedule 20.03.2017