Android radio button uncheck
Asked Answered
F

7

5

The application is a step sequencer application with 16 radio groups with 8 buttons in each group. It works perfectly except once a group has a button selected I cant turn it off unless I use the clear button I have created to clear all radiogroups. What I would like to add is some code that says when a selected radio button is selected again it simply turns off like a toggle. I tried using toggles but then other issues arose with that method. Below are two attempts but both simply stops me using the button

final RadioGroup radioGroup1 = (RadioGroup) findViewById(R.id.RadioGroup1);
RadioButton D1 = (RadioButton) findViewById(R.id.RadioButtonD1);

Button D1 = (Button) findViewById(R.id.RadioButtonD1);
D1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick (View v){
        PdBase.sendFloat("D1", 74);
        int selectedTypeId = radioGroup1.getCheckedRadioButtonId();
        RadioButton D1 = (RadioButton) findViewById(selectedTypeId);
        if (D1 != null) // This will be null if none of the radio buttons are selected
            radioGroup1.clearCheck();
        PdBase.sendFloat("D1", 0);
    }
});

RadioButton lC1 = (RadioButton) findViewById(R.id.RadioButtonlowC1);
lC1.setOnClickListener(new View.OnClickListener() {
    public void onClick (View v) {
        int selectedTypeId = radioGroup1.getCheckedRadioButtonId();

        RadioButton lC1 = (RadioButton) findViewById(R.id.RadioButtonlowC1);
        if (selectedTypeId == -1) {
            PdBase.sendFloat("lC1", 72);
        }
        else if (selectedTypeId == R.id.RadioButtonlowC1) {
            radioGroup1.clearCheck();
            PdBase.sendFloat("lC1", 0);
        }
    }
});
Flurried answered 5/4, 2013 at 14:40 Comment(6)
Why do not you just add an OFF button to each group?Azrael
This isn't usually how RadioButtons work and not what people expect. You should add a RadioButton like none to your groupCreolacreole
I could do that but as it is monophonic I want only one selected in each groupFlurried
Having a clear button for each group would work but not be very practicalFlurried
You will only get one selected in each group anyway. That is how radio buttons work. Your problem from a design perspective is that you are effectively using no button selected as an extra condition, which you have no way of toggling.Azrael
possible duplicate of Unchecking a radio buttonUndercroft
U
25

I recently had the same need - to have a radio group where the selected item could be deselected by tapping it again. I found that I couldn't accomplish that using listeners but I was able to do it using a custom RadioButton, like so...

public class ToggleableRadioButton extends RadioButton {
    // Implement necessary constructors

    @Override
    public void toggle() {
        if(isChecked()) {
            if(getParent() instanceof RadioGroup) {
                ((RadioGroup)getParent()).clearCheck();
            }
        } else {
            setChecked(true);
        }
    }
}

Notice that the button is toggled in different ways depending on its current state - i.e., calling setChecked(true) on the button vs. calling clearCheck() on the group. If setChecked() is used in both cases, a button that was just deselected cannot be immediately re-selected - the logic in RadioGroup seems to immediately deselect it.

To use this button, just replace your <RadioButton> tags with <your.package.ToggleableRadioButton> in your layout XML.

Undercroft answered 7/3, 2014 at 22:47 Comment(1)
getting ERROR when i implementing the constructor LOGCAT:- ToggleableRadioButton.<init> [class android.content.Context, interface android.util.AttributeSet]Lavabo
G
7

I just used the answer from @spaaarky21

and my full code look like this and it is working fine!

Java Class

public class ToggleableRadioButton extends RadioButton {


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

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

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ToggleableRadioButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void toggle() {
        if(isChecked()) {
            if(getParent() instanceof RadioGroup) {
                ((RadioGroup)getParent()).clearCheck();
            }
        } else {
            setChecked(true);
        }
    }
}

And for the XML layout

<com.smart_dent.adapters.ToggleableRadioButton android:id="@+id/tejido_blando_perfil_convexo"
                                 android:layout_width="wrap_content"
                                 android:layout_height="wrap_content"
                                 android:text="@string/tejido_blando_convexo_label" />

In this case you just need to change the package, I this is easy to find, it is just at the top of the Java Class Flie (if you created it from Android Studio)

Gasper answered 23/6, 2016 at 9:39 Comment(0)
R
5

It actually can be done with listeners but with an OnTouchListener, which will trigger before the button's state has changed, instead of the usual OnClickListener. The following works for me:

View.OnTouchListener radioButtonOnTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (((RadioButton) v).isChecked()) {
            // If the button was already checked, uncheck them all
            radioGroup.clearCheck();
            // Prevent the system from re-checking it
            return true;
        }
        return false;
    }
};
radioButton1.setOnTouchListener(radioButtonOnTouchListener);
radioButton2.setOnTouchListener(radioButtonOnTouchListener);

Where radioGroup is the parent of radioButton1 and radioButton2

Romo answered 10/9, 2015 at 8:36 Comment(2)
onTouch() is fairly low level. It seems like this would deselect the button for gestures other than a tap/click.Undercroft
Hmm, good point, @spaaarky21. I guess we should also check that the event is of type ACTION_DOWN. Although, testing this, I haven't been able to trigger anything that seemed abnormalRomo
V
4

Edit from @spaaarky21 answer

@Override
public void toggle() {
    if (isChecked()) {
        if (getParent() instanceof RadioGroup) {
            ((RadioGroup) getParent()).clearCheck();
        } 
        // add else here when a single radioButton without radioGroup
        else {
            setChecked(false);
        }
    } else {
        setChecked(true);
    }
}
Vogeley answered 10/10, 2016 at 3:14 Comment(0)
B
1

This is also doing the job:

public final class ToggleAbleRadioButton extends AppCompatRadioButton {
  public ToggleAbleRadioButton(final Context context, final AttributeSet attrs) {
    super(context, attrs);
  }

  @Override public void toggle() {
    setChecked(!isChecked());
  }
}
Boff answered 8/3, 2017 at 14:22 Comment(1)
not work, if you check twice it's not checked again, because thos code in appCompatRadioButoon - if (mBroadcasting) { return; }Winegrower
T
0

You can use a boolean to toggle the button on and off.

Add a boolean somewhere in your code:

var radioButton1IsSelected = false

Then setup the onClickListener for the button:

radioButton1.setOnClickListener {
        radioButton1IsSelected = !radioButton1IsSelected
        radioButton1.isChecked = radioButton1IsSelected
    }
Tainataint answered 30/10, 2020 at 22:50 Comment(0)
B
0

Here is the kotlin version of the custom ToggleableRadioButton to uncheck without needing to use RadioGroup.

class ToggleableRadioButton constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
        AppCompatRadioButton(context, attrs, defStyleAttr) {

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    override fun toggle() {
        isChecked = !isChecked
    }
}

With its default settings, i.e. super.toggle() does not uncheck since it is explicitly controlled by the RadioButton.java

RadioButton Toggle Source Code

As it is stated in the documentation, if the radio button is already checked, the toggle will not be called.

Basting answered 28/9, 2023 at 15:48 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.