Custom layout for RadioButton

theblitz picture theblitz · May 13, 2013 · Viewed 18k times · Source

Is there any way I can change the layout for a RadioButton and still have the RadioGroup recognise it?

what I need is that the layout will include a couple of EditText fields so that when the user selected that button those fields become active. I know I can built a custom part based on LinearLayout and set my own layout using: (LinearLayout) LayoutInflater.from(context).inflate(R.layout.my_layout, this, true) but can't figure out how to do the same thing with a radio button.

I have tried the option of having the extra fields outside the RadioGroup and lining them up with the button but it simply doesn't work. It seems to be too device-dependant.

This is what the original layout looked like:

    <RadioGroup
    android:id="@+id/time_selector_radio_group"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/time_selector_hours_prompt"
    android:layout_below="@id/time_selector_hours_prompt"
    android:layout_alignParentRight="true"
    android:gravity="right"
    android:orientation="vertical"
    android:checkedButton="@+id/time_selector_first_radio"
    >

    <RadioButton
        android:id="@+id/time_selector_first_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:button="@drawable/radio_button_selector"
        />
    <RadioButton
        android:id="@+id/time_selector_second_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:button="@drawable/radio_button_selector"
        />
    <RadioButton
        android:id="@+id/time_selector_third_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:button="@drawable/radio_button_selector"
        />
    <RadioButton
        android:id="@+id/time_selector_hours_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:button="@drawable/radio_button_selector"
        />

</RadioGroup>
<TextView
    android:id="@+id/time_selector_all_day_prompt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/time_selector_radio_group"
    android:layout_below="@id/time_selector_hours_prompt"
    android:layout_marginTop="11dip"
    android:text="@string/time_all_day"
    />
<TextView
    android:id="@+id/time_selector_before_noon_prompt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/time_selector_radio_group"
    android:layout_below="@id/time_selector_all_day_prompt"
    android:layout_marginTop="19dip"
    android:text="@string/time_before_noon"
    />
<TextView
    android:id="@+id/time_selector_after_noon_prompt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/time_selector_radio_group"
    android:layout_below="@id/time_selector_before_noon_prompt"
    android:layout_marginTop="19dip"
    android:text="@string/time_after_noon"
    />
<TextView
    android:id="@+id/time_selector_starting_time_prompt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@id/time_selector_starting_date_prompt"
    android:layout_below="@id/time_selector_after_noon_prompt"
    android:layout_marginTop="20dip"
    android:layout_marginLeft="2dip"
    android:text="@string/advanced_time_selector_dialog_starting_time_prompt"
    />
<EditText
    android:id="@+id/time_selector_starting_time"
    android:layout_width="@dimen/advanced_time_selector_edit_texts_width"
    android:layout_height="wrap_content"
    android:layout_alignRight="@id/time_selector_starting_date"
    android:layout_alignBaseline="@id/time_selector_starting_time_prompt"
    android:textSize="14sp"
    android:paddingRight="10dip"
    android:paddingLeft="10dip"
    android:gravity="center"
    android:singleLine="true"
    android:maxWidth="@dimen/advanced_time_selector_edit_texts_width"
    android:background="@drawable/text_field_bg"
    android:inputType="datetime"
    />
<TextView
    android:id="@+id/time_selector_ending_time_prompt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@id/time_selector_ending_date_prompt"
    android:layout_alignBottom="@id/time_selector_starting_time_prompt"
    android:layout_alignBaseline="@id/time_selector_starting_time_prompt"
    android:layout_marginRight="2dip"
    android:layout_marginLeft="2dip"
    android:text="@string/ending_date_prompt"
    />
<EditText
    android:id="@+id/time_selector_ending_time"
    android:layout_width="@dimen/advanced_time_selector_edit_texts_width"
    android:layout_height="wrap_content"
    android:layout_alignRight="@id/time_selector_ending_date"
    android:layout_alignBaseline="@id/time_selector_ending_time_prompt"
    android:textSize="14sp"
    android:paddingRight="10dip"
    android:paddingLeft="10dip"
    android:gravity="center"
    android:singleLine="true"
    android:maxWidth="@dimen/advanced_time_selector_edit_texts_width"
    android:background="@drawable/text_field_bg"
    android:inputType="datetime"
    />

Note that the button doesn't have any text and it is added in a TextView so that we can have it on the left. What was happening was that the text was "creeping up".

So, I changed it to look like this:

<RadioGroup
    android:id="@+id/time_selector_radio_group"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/time_selector_hours_prompt"
    android:layout_below="@id/time_selector_hours_prompt"
    android:layout_alignParentRight="true"
    android:layout_marginRight="30dip"
    android:gravity="right"
    android:orientation="vertical"
    android:checkedButton="@+id/time_selector_first_radio"
    >

    <RadioButton
        android:id="@+id/time_selector_all_day_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:button="@null"
        android:drawableRight="@drawable/radio_button_selector"
        android:text="@string/time_all_day"
        android:textColor="@color/content_text_color"
        />
    <RadioButton
        android:id="@+id/time_selector_before_noon_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:button="@null"
        android:drawableRight="@drawable/radio_button_selector"
        android:text="@string/time_before_noon"
        android:textColor="@color/content_text_color"
        />

    <RadioButton
        android:id="@+id/time_selector_after_noon_radio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dip"
        android:button="@null"
        android:drawableRight="@drawable/radio_button_selector"
        android:text="@string/time_after_noon"
        android:textColor="@color/content_text_color"
        />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">   
        <RadioButton
            android:id="@+id/time_selector_hours_radio"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="1dip"
            android:button="@null"
            android:drawableRight="@drawable/radio_button_selector"
            android:layout_alignParentRight="true"
            android:text="@string/advanced_time_selector_dialog_starting_time_prompt"
            android:textColor="@color/content_text_color"
            android:layout_marginLeft="-1dip"
            android:paddingLeft="-1dip"
            />  
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_toLeftOf="@id/time_selector_hours_radio"
            android:layout_alignParentLeft="true">            
            <EditText
                android:id="@+id/time_selector_starting_time"
                android:layout_width="@dimen/advanced_time_selector_edit_texts_width"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:paddingRight="10dip"
                android:paddingLeft="10dip"
                android:gravity="center"
                android:singleLine="true"
                android:maxWidth="@dimen/advanced_time_selector_edit_texts_width"
                android:background="@drawable/text_field_bg"
                android:layout_alignParentRight="true"
                android:layout_alignBaseline="@id/time_selector_hours_radio"
                android:inputType="datetime"
                />
            <TextView
                android:id="@+id/time_selector_ending_time_prompt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="2dip"
                android:layout_marginLeft="2dip"
                android:text="@string/ending_date_prompt"
                android:layout_alignBaseline="@id/time_selector_hours_radio"
                android:layout_toLeftOf="@id/time_selector_starting_time"
                />
            <EditText
                android:id="@+id/time_selector_ending_time"
                android:layout_width="@dimen/advanced_time_selector_edit_texts_width"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:paddingRight="10dip"
                android:paddingLeft="10dip"
                android:gravity="center"
                android:singleLine="true"
                android:maxWidth="@dimen/advanced_time_selector_edit_texts_width"
                android:layout_toLeftOf="@id/time_selector_ending_time_prompt"
                android:layout_alignBaseline="@id/time_selector_hours_radio"
                android:background="@drawable/text_field_bg"
                android:inputType="datetime"
                />
        </RelativeLayout>
    </RelativeLayout>

</RadioGroup>

It is still not perfect and, of course, it doesn't recognise it as a RadioGroup.

I wanted to go the direction of extending the RadioButton but have no idea how to change the layout there.

Answer

I&#39;m a frog dragon picture I'm a frog dragon · Dec 29, 2015

I wrote a custom RadioGroup called RadioGroupPlus where it will traverse through it's children and find RadioButton regardless how deep the RadioButton is nested, it will then link all the RadioButton found together.

You can find the repo here: https://github.com/worker8/RadioGroupPlus

The README of the repo covers how to use it, and it actually works just like how you imagine it, for example:

<worker8.com.github.radiogroupplus.RadioGroupPlus
    android:id="@+id/radio_group_plus"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <LinearLayout...>
       <ImageView...>
       <TextView...>
       <RadioButton...>
    </LinearLayout>
    <LinearLayout...>
       <ImageView...>
       <TextView...>
       <RadioButton...>
    </LinearLayout>
    <LinearLayout...>
       <ImageView...>
       <TextView...>
       <RadioButton...>
    </LinearLayout>
</worker8.com.github.radiogroupplus.RadioGroupPlus>

Will give you something like this:

In your case, since you already have the xml layout file, try to download RadioGroupPlus by following the guide here:

Add this to top level build.gradle:

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

Add this under dependencies:

compile 'com.github.worker8:RadioGroupPlus:v1.0.1'

Then in your xml, change RadioGroup to worker8.com.github.radiogroupplus.RadioGroupPlus. Now all your RadioButtons under RadioGroupPlus should all be linked together.

Hope it helps!