在动态 LinearLayout 中添加 RadioGroup

Posted

技术标签:

【中文标题】在动态 LinearLayout 中添加 RadioGroup【英文标题】:Add RadioGroup in dynamic LinearLayout 【发布时间】:2018-10-11 19:04:55 【问题描述】:

我在我称为 parentLinearLayout 的 LinearLayout 中为应用程序动态生成单选按钮(例如:3 个单选按钮)。问题是,它们不会自动进入一个组,所以如果我检查一个按钮然后另一个,都检查而不是取消选中第一个。所以,我想我应该做一个 RadioGroup。

该应用本身是一个问卷调查应用,每个问题都有不同数量的可能答案。我从单选按钮布局创建作为单选按钮的答案数量。

问题是,我收到一条错误消息,提示我应该先删除旧视图,但如果这样做,我会丢失生成的线性布局:The specified child already has a parent. You must call removeView() on the child's parent first.

这是我的代码:

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());
    

有什么想法可以解决这个问题吗?谢谢

【问题讨论】:

【参考方案1】:
    您正在循环中的每次迭代期间创建一个新布局。 通过夸大新视图,您正在丢失旧视图 每次您使用相同的 id R.id.radiobtn 来查找视图并在布局中再次添加相同的视图时,这是不可能的,因此会出现问题。

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());
    

解决方案:

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());

【讨论】:

是的,关键是我有一个空白屏幕,并且布局只包含一个单选按钮。对于每次迭代,我都应该在空白屏幕上添加一个单选按钮,这就是我所做的。问题是,它们不像单选按钮,因为我可以选择多个,这就是我想要解决的问题。 更准确地说,我的应用是一个问卷调查应用,所以根据一个问题的答案数量,我分别添加单选按钮的数量。 是的,似乎工作正常,谢谢,但现在单选按钮不再按行对齐。 (它们应该在另一个之下)。 然后使用垂直方向而不是水平方向 您是否会偶然知道在绘制完所有内容后如何检查选择了哪个单选按钮?当我点击一个按钮时,看看哪个被选中了?【参考方案2】:

你已经很接近了,我想只要改变一些线条,你就可以走了。

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);

【讨论】:

【参考方案3】:

RadioGroups 是在幕后美化的 LinearLayouts,这意味着它们可以支持 任何 子级,但如果它们是 的直接子级,则只会将 RadioButtons 视为同一“组” >组。例如:

想象一下这个层次结构:

<RadioGroup> // THIS YOU HAVE IN XML
   <RadioButton 1> // ALL THESE YOU CREATE PROGRAMMATICALLY
   <RadioButton 2>
   <RadioButton 3>
</RadioGroup>

所以你的 XML 看起来像:

<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/your_radio_button"
            android:layout_width=“match_parent"
            android:layout_
            android:orientation="vertical">
            <!-- Radio Buttons will be programmatically added here -->
</RadioGroup>

所以……您以编程方式创建所有内容,这很好。你有一个“循环”……

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);

如果需要监听变化,显然添加一个普通的CompoundButton.OnCheckedChangeListener 并覆盖:

 @Override
 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
    // do what you need ;) 
 

请记住,当您执行 group.add(rb) 时,如果 Button 有 onCheckedChangeListener,它将被触发……如果您将其设置为选中(我认为即使您没有使用“false”也会触发”),因此您可能希望延迟监听器的分配,直到您完成向 RadioGroup 添加按钮,然后迭代它们并同时添加它们(这不会触发回调,因为按钮是已经在层次结构中并且没有改变)。

如果您需要插入其他的东西而不是 RadioButton 作为您的RadioGroup 的直接子级,这是另一个问题的主题(它是可行的,不是自动的,并且需要您做一些额外的 -工作)。

【讨论】:

以上是关于在动态 LinearLayout 中添加 RadioGroup的主要内容,如果未能解决你的问题,请参考以下文章

安卓linearLayout动态添加控件

如何获取动态添加到LinearLayout的点击子视图的ID?

如何动态添加多个TextView到main.xml中定义的LinearLayout

LinearLayout系列:LinearLayout动态添加子View

动态的添加ImageView到LinearLayout中并居中显示

将视图动态添加到具有 wrap_content 高度的 LinearLayout 不会显示任何内容