onCheckChanged를 트리거하지 않고 Checkbox 값 변경 구현checkbox 전화 할 수있는 방법이 있습니까 checkbox.setChecked(false); 트리거하지

나는 setOnCheckedChangeListener내 구현checkbox

전화 할 수있는 방법이 있습니까

checkbox.setChecked(false);

트리거하지 않고 onCheckedChanged



답변

아니요, 할 수 없습니다. 이 onCheckedChanged메소드는에서 직접 호출됩니다 setChecked. 할 수있는 일은 다음과 같습니다.

mCheck.setOnCheckedChangeListener (null);
mCheck.setChecked (false);
mCheck.setOnCheckedChangeListener (mListener);

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

답변

OnCheckedChangeListener 안에이 코드를 추가하십시오 :

if(!compoundButton.isPressed()) {
            return;
}

이것은 프로그램 적으로 또는 사용자 조치에 의해 날씨 checkBox 상태가 변경되었음을 알아내는 데 도움이됩니다.


답변

이를 가능하게하는 또 다른 방법은 커스텀 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();
    }
}

원하는 경우 Kotlin 버전 :

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

샘플 사용법 :

checkBox.setChecked(true,false);

답변

당신은 단순히 setonclickListener 사용하면 잘 작동하며 이것은 매우 간단한 방법입니다. 감사합니다 🙂


답변

@Shade answer와 함께 Kotlin의 확장 기능 사용 :

fun CompoundButton.setCustomChecked(value: Boolean,listener: CompoundButton.OnCheckedChangeListener) {
     setOnCheckedChangeListener(null)
     isChecked = value
     setOnCheckedChangeListener(listener)
}

답변

이 문제를 우연히 발견하는 사람에게는 확인란에서 태그를 사용한 다음 해당 수신기에서 해당 태그를 확인하는 것입니다 (코드는 Kotlin에 있음).

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

그런 다음 액세스 할 때 값 변경을 무시하려는 경우 isChecked를 true로 설정하기 전에 태그를 true로 설정하십시오.

checkBox.tag = true
checkBox.isChecked = true

이해가 걱정되는 경우 키가 필요한 대체 setTag 메소드를 사용하여 태그를 키에 맵핑 할 수도 있습니다. 그러나 모든 것이 단일 클래스에 포함되어 있으면 몇 가지 주석 문자열로 인해 발생하는 상황을 설명하기에 충분합니다.


답변

이 SafeCheckBox 클래스를 확인란으로 사용할 수 있습니다.

public class SafeCheckBox extends AppCompatCheckBox implements CompoundButton.OnCheckedChangeListener {

    private OnSafeCheckedListener onSafeCheckedListener;

    private int mIgnoreListener = CALL_LISTENER;

    public static final int IGNORE = 0;
    public static final int CALL_LISTENER = 1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({IGNORE, CALL_LISTENER})
    public @interface ListenerMode {
    }

    public SafeCheckBox(Context context) {
        super(context);
        init(context);
    }

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

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

    /**
     * @param checkState     change state of the checkbox to
     * @param mIgnoreListener true to ignore the listener else listener will be  notified
     */
    public void setSafeCheck(boolean checkState, @ListenerMode int mIgnoreListener) {
        if (isChecked() == checkState) return; //already in the same state no need to fire listener. 

        if (onSafeCheckedListener != null) { // this to avoid a bug if the user listens for the event after using this method and in that case he will miss first check
            this.mIgnoreListener = mIgnoreListener;
        } else {
            this.mIgnoreListener = CALL_LISTENER;
        }
        setChecked(checkState);
    }

    private void init(Context context) {
        setOnCheckedChangeListener(this);
    }


    public OnSafeCheckedListener getOnSafeCheckedListener() {
        return onSafeCheckedListener;
    }

    public void setOnSafeCheckedListener(OnSafeCheckedListener onSafeCheckedListener) {
        this.onSafeCheckedListener = onSafeCheckedListener;
    }

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

        if (onSafeCheckedListener != null)
            onSafeCheckedListener.onAlwaysCalledListener(buttonView, isChecked);// this has to be called before onCheckedChange
        if (onSafeCheckedListener != null && (mIgnoreListener == CALL_LISTENER)) {
            onSafeCheckedListener.onCheckedChanged(buttonView, isChecked);
        }
        mIgnoreListener = CALL_LISTENER;
    }

    /**
     * Listener that will be called when you want it to be called.
     * On checked change listeners are called even when the setElementChecked is called from code. :(
     */
    public interface OnSafeCheckedListener extends OnCheckedChangeListener {
        void onAlwaysCalledListener(CompoundButton buttonView, boolean isChecked);
    }
}
  • 그럼 당신은 전화 할 수 있습니다 :-

    setSafeCheck(true,ListenerMode.IGNORE);// OnCheckedChange listener will not be notified