Reputation: 387
I dynamically generate radiobuttons for an app (ex: 3 radiobuttons) in a LinearLayout I call parentLinearLayout
. Problem is, they don't go automatically in a group, so if I check a button and then another, both check instead of un-checking the first one. So, I thought I should do a RadioGroup.
The app itself is a questionnaire app, and every question has a different number of possible answers. I create from a radiobutton layout the number of answers as radiobuttons.
Problem is, I get an error saying that I should remove the old view before doing so, but if I do this I lose my generated linearlayout: The specified child already has a parent. You must call removeView() on the child's parent first.
Here is my code:
public void drawRAnswers(int pst){
int drawables = qmclist.get(pst).getAnswers().size();
RadioGroup l1 = new RadioGroup(this);
for (int i=0;i<drawables;i++){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.radiobutton, null);
// Add the new row before the add field button.
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount());
rowView.setId(i);
RadioButton rd = (RadioButton) rowView.findViewById(R.id.radiobtn);
l1.addView(rd); <== HERE IS THE PROBLEM
rd.setText(current.getAnswers().get(i).getAns());
}
}
Any ideas how I could fix this? Thanks
Upvotes: 1
Views: 978
Reputation: 27246
RadioGroups
are glorified LinearLayouts behind the scenes, that means they can support any children, but will only treat RadioButtons
in the same “group” if they are direct children of the Group. E.g.:
Imagine This hierarchy:
<RadioGroup> // THIS YOU HAVE IN XML
<RadioButton 1> // ALL THESE YOU CREATE PROGRAMMATICALLY
<RadioButton 2>
<RadioButton 3>
</RadioGroup>
So your XML looks like:
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/your_radio_button"
android:layout_width=“match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Radio Buttons will be programmatically added here -->
</RadioGroup>
So… you create everything programmatically, that’s fine. You have a “loop” like…
final RadioGroup group = //find your_radio_button in the layout.
// now iterate
for (Something something : listOfSomethings) {
final RadioButton rb = new RadioButton(context);
rb.setId(View.generateViewId());
rb.setText(something.giveMeTheText());
rb.setLayoutParams(layoutParams); // make these depending what your container for the RadioGroup is.
rb.setOnCheckedChangeListener(your OnCheckedChangeListener);
group.add(rb);
}
If you need to listen for changes, obviously add a common CompoundButton.OnCheckedChangeListener
and override:
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// do what you need ;)
}
Bear in mind that the moment you do group.add(rb)
if the Button has an onCheckedChangeListener
, it will be fired… if you set it as checked (I think it also fires even if you don’t with a “false”), so you may want to delay the assignment of the listener until you’re done adding buttons to the RadioGroup and then iterate them and add them all at the same time (that doesn’t trigger the callback right there because the buttons are ALREADY in the hierarchy and haven’t changed).
If you need to insert something other than a RadioButton as the direct child of your RadioGroup
that’s the topic for another question (it’s doable, not automatic and will require you to do some extra-work).
Upvotes: 1
Reputation: 11018
You are quite close I guess just change some of the lines and you are good to go.
public void drawRAnswers(int pst){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int drawables = qmclist.get(pst).getAnswers().size();
RadioGroup l1 = new RadioGroup(this);
for (int i=0;i<drawables;i++){
final View rowView = inflater.inflate(R.layout.radiobutton, null);
// Add the new row before the add field button.
RadioButton rd = (RadioButton) rowView.findViewById(R.id.radiobtn);
rd.setText(current.getAnswers().get(i).getAns());
rd.setId(i);
l1.addView(rd);
}
parentLinearLayout.addView(l1, parentLinearLayout.getChildCount());
//or
parentLinearLayout.addView(l1);
}
Upvotes: 1
Reputation: 37404
R.id.radiobtn
for to find a view and add the same view again in the layout which is not possible hence the issue.for (int i=0;i<drawables;i++){
// 1,2
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//
final View rowView = inflater.inflate(R.layout.radiobutton, null);
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount());
rowView.setId(i);
RadioButton rd = (RadioButton) rowView.findViewById(R.id.radiobtn);
l1.addView(rd); // same view with same id R.id.radiobtn
rd.setText(current.getAnswers().get(i).getAns());
}
Solution :
public void drawRAnswers(int pst){
int drawables = qmclist.get(pst).getAnswers().size();
// create a radio group as container with direction
RadioGroup l1 = new RadioGroup(this);
l1.setOrientation(LinearLayout.VERTICAL);
for (int i=0;i<drawables;i++){
// create radio button, with id and text
RadioButton rd = new RadioButton(this);
rd.setId(i);
rd.setText(current.getAnswers().get(i).getAns());
// add radio button into group
l1.addView(rd);
}
// finally, add radio group with buttons into parent layout
parentLinearLayout.addView(l1, parentLinearLayout.getChildCount());
}
Upvotes: 2