Android - 以编程方式更改交换机的状态,而不触发OnCheckChanged侦听器

时间:2014-09-03 10:32:23

标签: java android onclicklistener oncheckedchanged android-switch


我正在寻找一种使用switch.setChecked(true);以编程方式更改Android Switch小部件状态的方法,而不会触发OnCheckedChangedlistener

我的第一个想法是将它换成OnClickListener,但因为这只记录点击次数,你不仅可以点击而且还可以滑动一个Switch然后它不是真的如果用户要将开关从关闭滑到开启,那么开关实际上什么都不做,因为用户没有点击...

如果有人有解决方案或一个聪明的工作,这将是非常棒的

10 个答案:

答案 0 :(得分:32)

在调用 setCheck()函数之前将侦听器设置为 null ,之后启用,如下所示:

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

参考Change Checkbox value without triggering onCheckChanged

答案 1 :(得分:29)

好吧,就在使用交换机进行代码处理之前,您可以取消注册监听器,然后执行您需要的任何操作,并再次注册监听器。

答案 2 :(得分:16)

我有一个解决方案,我的工作正常。 我在我的开关控件上添加了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。

当您尝试更改切换控件的检查状态时,也不要忘记添加有效的字符串标记(非空)。 喜欢:

 mMySwitch.setTag("TAG");
 mMySwitch.setChecked(true);

答案 3 :(得分:7)

编写自定义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;
}

}

答案 4 :(得分:2)

每个CompoundButton(两个状态按钮-开/关)都有一个 pressed 状态,仅当用户按下视图时该状态为真

只需在启动实际逻辑之前在您的侦听器中添加一个检查:

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

这样,以编程方式更改检查值不会触发不需要的代码。

来自@krisDrOid的答案。

答案 5 :(得分:1)

我能找到的最佳解决方案是;

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

答案 6 :(得分:0)

使用此 switch.setChecked(true); // first set value (from pref or server or anywhere) and than switch.setOnCheckedChangeListener (this);添加侦听器。

答案 7 :(得分:0)

如果这里没有任何效果,这是一个棘手的解决方案。

在 switch 顶部创建一个 textview 并将 clickListener 添加到 textview。

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

为 textview 添加 elavation。

答案 8 :(得分:-1)

阐述马哈茂德的回答

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

`

答案 9 :(得分:-5)

只需将其添加到您的代码中:

activity.recreate();