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.
Use the android:orientation="horizontal" -attribute of the RadioGroup.
To create each radio button option, create a RadioButton in your layout. However, because radio buttons are mutually exclusive, you must group them together inside a RadioGroup . By grouping them together, the system ensures that only one radio button can be selected at a time.
To make a horizontal radio button set, add the data-type="horizontal" to the fieldset . The framework will float the labels so they sit side-by-side on a line, hide the radio button icons and only round the left and right edges of the group.
For creating dynamic RadioButton, we need to use android. view. ViewGroup. LayoutParams which configures the width and height of views and implements setOnCheckedChangeListener() method of RadioGroup class.
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 RadioButton
s under RadioGroupPlus
should all be linked together.
Hope it helps!
You'll have to create a class that extends RadioGroup, and override addView and PassThroughHierarchyChangeListener, to be able to use custom layouts for your radio button. By default, RadioGroup assumes that its children are radio buttons, see code below from the RadioGroup class:
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (child instanceof RadioButton) {
final RadioButton button = (RadioButton) child;
if (button.isChecked()) {
mProtectFromCheckedChange = true;
if (mCheckedId != -1) {
setCheckedStateForView(mCheckedId, false);
}
mProtectFromCheckedChange = false;
setCheckedId(button.getId());
}
}
super.addView(child, index, params);
}
private class PassThroughHierarchyChangeListener implements
ViewGroup.OnHierarchyChangeListener {
private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener;
/**
* {@inheritDoc}
*/
public void onChildViewAdded(View parent, View child) {
if (parent == RadioGroup.this && child instanceof RadioButton) {
int id = child.getId();
// generates an id if it's missing
if (id == View.NO_ID) {
id = View.generateViewId();
child.setId(id);
}
((RadioButton) child).setOnCheckedChangeWidgetListener(
mChildOnCheckedChangeListener);
}
if (mOnHierarchyChangeListener != null) {
mOnHierarchyChangeListener.onChildViewAdded(parent, child);
}
}
/**
* {@inheritDoc}
*/
public void onChildViewRemoved(View parent, View child) {
if (parent == RadioGroup.this && child instanceof RadioButton) {
((RadioButton) child).setOnCheckedChangeWidgetListener(null);
}
if (mOnHierarchyChangeListener != null) {
mOnHierarchyChangeListener.onChildViewRemoved(parent, child);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With