Change Checkbox value without triggering onCheckChanged

前端 未结 19 983
广开言路
广开言路 2020-11-30 00:18

I have setOnCheckedChangeListener implemented for my checkbox

Is there a way I can call

checkbox.setChecked(false);
         


        
相关标签:
19条回答
  • 2020-11-30 00:38

    I used a ReentrantLock, and lock it whenever I'm setting isChecked:

    Kotlin:

    // lock when isChecked is being set programmatically
    val isBeingProgrammaticallySet = ReentrantLock()
    
    // set isChecked programmatically
    isBeingProgrammaticallySet.withLock()
    {
        checkbox.isChecked = true
    }
    
    // do something only when preference is modified by user
    checkbox.setOnCheckedChangeListener()
    {
        _,isChecked ->
        if (isBeingProgrammaticallySet.isHeldByCurrentThread.not())
        {
            // do it
        }
    }
    
    0 讨论(0)
  • 2020-11-30 00:39

    I didn't really want to be having to pass the listener in each time we set checked changed, nor using enabled as a way of determining whether we should set the value (what happens in the case we have the switch disabled already when setting the value?)

    Instead I'm making use of tags with an id and a couple of extension methods you can call:

    fun CompoundButton.setOnCheckedWithoutCallingChangeListener(
        listener: (view: CompoundButton, checked: Boolean) -> Unit
    ) {
        setOnCheckedChangeListener { view, checked ->
            if (view.getTag(R.id.compound_button_checked_changed_listener_disabled) != true) {
                listener(view, checked)
            }
        }
        this.setTag(R.id.compound_button_enabled_checked_change_supported, true)
    }
    
    fun CompoundButton.setCheckedWithoutCallingListener(checked: Boolean) {
        check(this.getTag(R.id.compound_button_enabled_checked_change_supported) == true) {
            "Must set listener using `setOnCheckedWithoutCallingChangeListener` to call this method" 
        }
    
        setTag(R.id.compound_button_checked_changed_listener_disabled, true)
        isChecked = checked
        setTag(R.id.compound_button_checked_changed_listener_disabled, false)
    }
    

    Now you can call setCheckedWithoutCallingListener(bool) and it will enforce the correct listener usage.

    You can also still call setChecked(bool) to fire the listener if you still need it

    0 讨论(0)
  • 2020-11-30 00:42

    Using Kotlin's extensions with @Shade answer :

    fun CompoundButton.setCustomChecked(value: Boolean,listener: CompoundButton.OnCheckedChangeListener) {
         setOnCheckedChangeListener(null)
         isChecked = value
         setOnCheckedChangeListener(listener)
    }
    
    0 讨论(0)
  • 2020-11-30 00:45

    This is a simple solution I used:
    Define a custom listener:

    class CompoundButtonListener implements CompoundButton.OnCheckedChangeListener {
    
        boolean enabled = false;
    
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
    
        }
    
        void enable() {
            enabled = true;
        }
    
        void disable() {
            enabled = false;
        }
    
        boolean isEnabled() {
            return enabled;
        }
    }
    

    Initialization:

    CompoundButtonListener checkBoxListener = new CompoundButtonListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
            if (isEnabled()) {
                // Your code goes here
            }
        }
    };
    myCheckBox.setOnCheckedChangeListener(checkBoxListener);
    

    Usage:

    checkBoxListener.disable();
    
    // Some logic based on which you will modify CheckBox state
    // Example: myCheckBox.setChecked(true)
    
    checkBoxListener.enable();
    
    0 讨论(0)
  • 2020-11-30 00:45
    public void setCheckedChangeListenerSwitch() {
    
        switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean selected) {
    
                if (selected) {
                    // do something
                } else {
                    // do something else
                }
    
            }
        });
    
    }
    
    // Update state & reset listener (so onCheckedNot called)
    public void updateSwitchState(boolean state){
    
        switch.setOnCheckedChangeListener(null);
        switch.setChecked(state);
        setCheckedChangeListenerSwitch();
    
    }
    
    0 讨论(0)
  • 2020-11-30 00:46

    For anyone that stumbles across this, one simpler way to do this is to just use a tag on the checkbox and then check that tag on its listener (code is in Kotlin):

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

    Then when accessing just set the tag to true before you set the isChecked to true when you want to ignore the value change:

    checkBox.tag = true
    checkBox.isChecked = true
    

    You could also map the tag to a key by using the alternative setTag method that requires a key if you were worried about understandability. But if its all contained to a single class a few comment strings will be more than enough to explain whats happening.

    0 讨论(0)
提交回复
热议问题