Как я могу различить, изменяется ли Switch, Checkbox Value пользователем или программно (в том числе путем сохранения)? - PullRequest
96 голосов
/ 03 февраля 2012
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();
            }
        });

Как реализовать метод isNotSetByUser()?

Ответы [ 15 ]

1 голос
/ 22 января 2019

Мой вариант с функциями расширения Kotlin:

fun CheckBox.setCheckedSilently(isChecked: Boolean, onCheckedChangeListener: CompoundButton.OnCheckedChangeListener) {
    if (isChecked == this.isChecked) return
    this.setOnCheckedChangeListener(null)
    this.isChecked = isChecked
    this.setOnCheckedChangeListener(onCheckedChangeListener)
}

... к сожалению, нам нужно каждый раз передавать onCheckedChangeListener, потому что класс CheckBox не имеет метода get для поля mOnCheckedChangeListener ((

Использование:

checkbox.setCheckedSilently(true, myCheckboxListener)
1 голос
/ 14 сентября 2018

Вот моя реализация

Java-код для пользовательского коммутатора:

public class CustomSwitch extends SwitchCompat {

private OnCheckedChangeListener mListener = null;

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

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

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

@Override
public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {
    if(listener != null && this.mListener != listener) {
        this.mListener = listener;
    }
    super.setOnCheckedChangeListener(listener);
}

public void setCheckedSilently(boolean checked){
    this.setOnCheckedChangeListener(null);
    this.setChecked(checked);
    this.setOnCheckedChangeListener(mListener);
}}

Эквивалентный код Котлина:

class CustomSwitch : SwitchCompat {

private var mListener: CompoundButton.OnCheckedChangeListener? = null

constructor(context: Context) : super(context) {}

constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}

constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}

override fun setOnCheckedChangeListener(@Nullable listener: CompoundButton.OnCheckedChangeListener?) {
    if (listener != null && this.mListener != listener) {
        this.mListener = listener
    }
    super.setOnCheckedChangeListener(listener)
}

fun setCheckedSilently(checked: Boolean) {
    this.setOnCheckedChangeListener(null)
    this.isChecked = checked
    this.setOnCheckedChangeListener(mListener)
}}

Чтобы изменить состояние коммутатора без запуска использования слушателя:

swSelection.setCheckedSilently(contact.isSelected)

Вы можете следить за изменением состояния как обычно:

swSelection.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
   @Override
   public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
      // Do something
   }       
 });

В Kotlin:

 swSelection.setOnCheckedChangeListener{buttonView, isChecked -> run {
            contact.isSelected = isChecked
        }}
0 голосов
/ 01 марта 2019

Я создал расширение с PublishSubject в RxJava, простое. Реагирует только на события «OnClick».

/**
 * Creates ClickListener and sends switch state on each click
 */
fun CompoundButton.onCheckChangedByUser(): PublishSubject<Boolean> {
    val onCheckChangedByUser: PublishSubject<Boolean> = PublishSubject.create()
    setOnClickListener {
        onCheckChangedByUser.onNext(isChecked)
    }
    return onCheckChangedByUser
}
0 голосов
/ 10 июня 2014

Если тег представления не используется, вы можете использовать его вместо расширения флажка:

        checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                @Override
                public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
                    if (buttonView.getTag() != null) {
                        buttonView.setTag(null);
                        return;
                    }
                    //handle the checking/unchecking
                    }

каждый раз, когда вы вызываете что-то, что ставит / снимает флажок, также вызывайте его перед установкой / снятием отметки:

checkbox.setTag(true);
0 голосов
/ 03 февраля 2012

Создать переменную

boolean setByUser = false;  // Initially it is set programmatically


private void notSetByUser(boolean value) {
   setByUser = value;
}
// If user has changed it will be true, else false 
private boolean isNotSetByUser() {
   return setByUser;          

}

В приложении, когда вы изменяете его вместо пользователя, вызывайте notSetByUser(true), чтобы он не был установлен пользователем, в противном случае вызывайте notSetByUser(false), т.е. он устанавливается программой.

Наконец, в вашем прослушивателе событий после вызова isNotSetByUser () убедитесь, что вы снова изменили его на нормальный.

Вызывайте этот метод всякий раз, когда вы выполняете это действие пользователем или программно. Вызовите notSetByUser () с соответствующим значением.

...