Android: How to get a radiogroup with togglebuttons?

Here is how I managed to do it (no RadioGroup involved):

private CompoundButton.OnCheckedChangeListener toggleListener = new CompoundButton.OnCheckedChangeListener()
{
    boolean avoidRecursions = false;

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
    {
        if(avoidRecursions) return;
        avoidRecursions = true;

        // don't allow the un-checking
        if(!isChecked)
        {
            buttonView.setChecked(true);
            avoidRecursions = false;
            return;
        }

        // un-check the previous checked button
        if(buttonView != toggleButton1 && toggleButton1.isChecked()) toggleButton1.setChecked(false);
        else if(buttonView != toggleButton2 && toggleButton2.isChecked()) toggleButton2.setChecked(false);
        else if(buttonView != toggleButton3 && toggleButton3.isChecked()) toggleButton3.setChecked(false);
        else if(buttonView != toggleButton4 && toggleButton4.isChecked()) toggleButton4.setChecked(false);

        avoidRecursions = false;
    }
};

// ...

toggleButton1.setOnCheckedChangeListener(toggleListener);
toggleButton2.setOnCheckedChangeListener(toggleListener);
toggleButton3.setOnCheckedChangeListener(toggleListener);
toggleButton4.setOnCheckedChangeListener(toggleListener);

I'd just re-use the RadioGroup like so: (please note the onClick attribute,i.e. a button click will trigger your Activity's onToggle(View) method.

<RadioGroup android:id="@+id/toggleGroup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:orientation="horizontal"
        >

    <ToggleButton android:id="@+id/btn_Letter"
                  android:layout_height="wrap_content"
                  android:layout_width="fill_parent"
                  android:layout_weight="1"
                  android:textSize="14sp"
                  android:textOn="Letter"
                  android:textOff="Letter"
                  android:onClick="onToggle"
                  android:checked="true"
            />
    <ToggleButton android:id="@+id/btn_A4"
                  android:layout_height="wrap_content"
                  android:layout_width="fill_parent"
                  android:layout_weight="1"
                  android:textSize="14sp"
                  android:textOn="A4"
                  android:textOff="A4"
                  android:onClick="onToggle"
            />
</RadioGroup>

In your Activity, or some place else, you can define a listener, e.g.

static final RadioGroup.OnCheckedChangeListener ToggleListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(final RadioGroup radioGroup, final int i) {
            for (int j = 0; j < radioGroup.getChildCount(); j++) {
                final ToggleButton view = (ToggleButton) radioGroup.getChildAt(j);
                view.setChecked(view.getId() == i);
            }
        }
    };

and register it, for instance in onCreate():

@Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     this.setContentView(R.layout.scan_settings);

     ((RadioGroup) findViewById(R.id.toggleGroup)).setOnCheckedChangeListener(ToggleListener);    
 }

finally in onToggle(View), you would do whatever needs to happen, specific to your app. and also call the RadioGroup's check method, with the toggled view's id. Like so:

public void onToggle(View view) {
    ((RadioGroup)view.getParent()).check(view.getId());
    // app specific stuff ..
}

You can use regular radio buttons and use an image for the RadioButton background and don't specify a text string:

<RadioButton 
android:id="@+id/custom_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
    android:button="@null"
    android:background="@drawable/button_custom"
    />

For the background, use any drawable, but most likely you'll want to use a selector to be able to provide different images for the different states. The simplest version uses just two images:

<item android:state_checked="true" android:state_pressed="true"
      android:drawable="@drawable/custom_selected" />
<item android:state_checked="false" android:state_pressed="true"
      android:drawable="@drawable/custom_normal" />

<item android:state_checked="true" android:state_focused="true"
      android:drawable="@drawable/custom_selected" />
<item android:state_checked="false" android:state_focused="true"
      android:drawable="@drawable/custom_normal" />

<item android:state_checked="false" android:drawable="@drawable/custom_normal" />
<item android:state_checked="true" android:drawable="@drawable/custom_selected" />

With this, the radio button looks like a regular button (or rather, looks like whatever drawable you provided) and behaves like a radio button in a radio group.


I tried all the methods outlined above and none really worked that well.

Trying to hack a radiobutton to look like a real button looks bad.

Eventually I just took the RadioGroup source code and Modified it to accept a ToggleButton rather than a RadioButton. Works really well!

Here is the source on Github: ToggleGroup

Usage:

    <com.rapsacnz.ToggleGroup
    android:id="@+id/deal_detail_toolbar"
    android:layout_width="fill_parent"
    android:layout_height="60dip"
    android:layout_alignParentBottom="true"
    android:background="@drawable/bgnd_toggle_button">
    <ToggleButton
        android:id="@+id/b1"
        android:textOn="@string/tab_1_label"
        android:textOff="@string/tab_1_label"
        android:textSize="10sp"
        android:textColor="@color/tab_button_color"
        android:checked="true"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_weight="1"
        android:drawableTop="@drawable/toggle_spotlight"
        android:drawablePadding="-5dp "
        android:gravity="bottom|center"
        android:paddingTop="10dp"
        android:paddingBottom="5dp"
        android:background="@drawable/bgnd_transparent" />
    <ToggleButton
        android:id="@+id/b2"
        android:textOn="@string/tab_2_label"
        android:textOff="@string/tab_2_label"
        android:textSize="10sp"
        android:textColor="@color/tab_button_color"
        android:checked="false"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_weight="1"
        android:drawableTop="@drawable/toggle_browse"
        android:gravity="bottom|center"
        android:paddingTop="10dp"
        android:paddingBottom="5dp"
        android:background="@drawable/bgnd_transparent" />

    <ToggleButton
        android:id="@+id/b3"
        android:textOn="@string/tab_3_label"
        android:textOff="@string/tab_3_label"
        android:textSize="10sp"
        android:textColor="@color/tab_button_color"
        android:checked="false"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_weight="1"
        android:drawableTop="@drawable/toggle_purchased"
        android:gravity="bottom|center"
        android:paddingTop="10dp"
        android:paddingBottom="5dp"
        android:background="@drawable/bgnd_transparent" />
</com.rapsacnz.ToggleGroup>

Hope this helps