更改复选框值而不触发onCheckChanged

Arc*_*pgc 127 checkbox android

setOnCheckedChangeListener为我实施了checkbox

有没有办法可以打电话

checkbox.setChecked(false);
Run Code Online (Sandbox Code Playgroud)

没有触发 onCheckedChanged

Sha*_*ade 255

不,你不能这样做.该onCheckedChanged方法直接从中调用setChecked.你能做的是以下几点:

mCheck.setOnCheckedChangeListener (null);
mCheck.setChecked (false);
mCheck.setOnCheckedChangeListener (mListener);
Run Code Online (Sandbox Code Playgroud)

查看CheckBox源代码,并执行setChecked:

public void  setChecked(boolean checked) {
    if (mChecked != checked) {
        mChecked = checked;
        refreshDrawableState();

        // Avoid infinite recursions if setChecked() is called from a listener
        if (mBroadcasting) {
            return;
        }

        mBroadcasting = true;
        if (mOnCheckedChangeListener != null) {
            mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
        }

        if (mOnCheckedChangeWidgetListener != null) {
            mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
        }

        mBroadcasting = false;            
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 嗯,不需要仅仅因为你不理解解决方案而进行投票.`mListener`是`OnCheckChangedListener`接口的一个实现,它是由程序员创建的.我的回答暗示程序员保持对**他们自己的实现的引用** - `mListener`. (18认同)
  • 您如何建议获得`mListener`?`Checkbox`的`OnCheckChangeListener`没有getter (6认同)
  • @Ren,更改侦听器只涉及`CheckBox`对象中的属性设置.我不会说那是低效的. (4认同)

kri*_*Oid 36

在OnCheckedChangeListener中添加此代码:

if(!compoundButton.isPressed()) {
            return;
}
Run Code Online (Sandbox Code Playgroud)

这将有助于我们找出天气检查框状态是以编程方式或用户操作更改的.

  • 意识到!这打破了无障碍模式!isPressed() 在语音助手模式下双击触发时不为真。 (11认同)
  • 这应该标记为解决方案,就像是魅力! (5认同)

and*_*per 19

实现此目的的另一种可能方法是使用自定义CheckBox,它允许您选择是否要调用侦听器:

public class CheckBox extends AppCompatCheckBox {
    private OnCheckedChangeListener mListener;

    public CheckBox(final Context context) {
        super(context);
    }

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

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

    @Override
    public void setOnCheckedChangeListener(final OnCheckedChangeListener listener) {
        mListener = listener;
        super.setOnCheckedChangeListener(listener);
    }

    public void setChecked(final boolean checked, final boolean alsoNotify) {
        if (!alsoNotify) {
            super.setOnCheckedChangeListener(null);
            super.setChecked(checked);
            super.setOnCheckedChangeListener(mListener);
            return;
        }
        super.setChecked(checked);
    }

    public void toggle(boolean alsoNotify) {
        if (!alsoNotify) {
            super.setOnCheckedChangeListener(null);
            super.toggle();
            super.setOnCheckedChangeListener(mListener);
        }
        super.toggle();
    }
}
Run Code Online (Sandbox Code Playgroud)

样品用量:

class CheckBox @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatCheckBox(context, attrs, defStyleAttr) {
    private var listener: CompoundButton.OnCheckedChangeListener? = null

    override fun setOnCheckedChangeListener(listener: CompoundButton.OnCheckedChangeListener?) {
        this.listener = listener
        super.setOnCheckedChangeListener(listener)
    }

    fun setChecked(checked: Boolean, alsoNotify: Boolean) {
        if (!alsoNotify) {
            super.setOnCheckedChangeListener(null)
            super.setChecked(checked)
            super.setOnCheckedChangeListener(listener)
            return
        }
        super.setChecked(checked)
    }

    fun toggle(alsoNotify: Boolean) {
        if (!alsoNotify) {
            super.setOnCheckedChangeListener(null)
            super.toggle()
            super.setOnCheckedChangeListener(listener)
        }
        super.toggle()
    }
}
Run Code Online (Sandbox Code Playgroud)


Roh*_*hit 12

你使用简单的setonclickListener,它将工作正常,这是非常简单的方法,谢谢:)

  • 当用户滑动开关时,不会调用onClick(). (33认同)
  • 实际上,当用户拖动切换时,这样做会使您没有处理程序. (2认同)

小智 11

很简单,你isPressed往里面查一下就可以了setOnCheckedChangeListener

科特林

switch.setOnCheckedChangeListener { buttonView, isChecked ->
    when {        
        buttonView.isPressed -> {
            foo(isChecked)
        }
    }
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 8

对于偶然发现此问题的任何人,一种更简单的方法是在复选框上使用标签,然后在其侦听器上检查该标签(代码在 Kotlin 中):

checkBox.tag = false
checkBox.setOnCheckedChangeListener{ buttonView, isChecked -> 
    if(checkBox.tag != true) {
        //Do some stuff
    } else {
        checkBox.tag = false
    }
Run Code Online (Sandbox Code Playgroud)

然后在访问时只需将标记设置为 true,然后将 isChecked 设置为 true 即可忽略值更改:

checkBox.tag = true
checkBox.isChecked = true
Run Code Online (Sandbox Code Playgroud)

如果您担心可理解性,您还可以使用需要键的替代 setTag 方法将标签映射到键。但是如果它全部包含在一个类中,那么几个注释字符串就足以解释发生了什么。


Mic*_*use 6

使用Kotlin的扩展@Shade答案:

fun CompoundButton.setCustomChecked(value: Boolean,listener: CompoundButton.OnCheckedChangeListener) {
     setOnCheckedChangeListener(null)
     isChecked = value
     setOnCheckedChangeListener(listener)
}
Run Code Online (Sandbox Code Playgroud)