以编程方式添加的RadioButtons拒绝服从LayoutParams加权

时间:2012-01-21 22:06:58

标签: android user-interface android-widget android-listview

我正在尝试在Android布局中创建RadioGroup,其中子RadioButton被拉伸以均匀地填充RadioGroup的整个宽度。但是,在尝试使用RadioButton s执行此操作时遇到了一些意外行为,这些行为是从代码中以编程方式添加的。首先是一些背景......

做什么工作

我开始使用基于RelativeLayout的简单布局,其底部包含大TextViewRadioGroup

main.xml 布局文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView android:text="Some text"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_above="@+id/radio_group"
        android:gravity="center"
        android:background="@android:color/holo_green_dark"
        />      
    <RadioGroup android:id="@+id/radio_group"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:background="@android:color/holo_blue_dark">         
        <RadioButton android:text="Option 1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/darker_gray"
            android:button="@android:color/transparent"
            android:padding="10dp"
            android:gravity="center"
            android:layout_margin="2dp"/>   
        <RadioButton android:text="Option 2"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/darker_gray"
            android:button="@android:color/transparent"
            android:padding="10dp"
            android:gravity="center"
            android:layout_margin="2dp"/> 
    </RadioGroup>       
</RelativeLayout>

在运行时生成以下布局:

Evenly distributed radio buttons

您可以看到,android:layout_width="wrap_content"android:layout_weight="1"RadioButton的使用会拉伸它们,以均匀地填充每个RadioGroup的一半RadioButton。到目前为止一切都很好。

什么不起作用

但是,我的要求是在运行时根据业务逻辑在此布局中动态创建RadioButton,而不是总是使用布局中静态包含的两个 - 有时我可能需要两个按钮,有时四个等。

为了实现这一点,我从 main.xml 布局中删除了<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:text="Some text" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_alignParentTop="true" android:layout_above="@+id/radio_group" android:gravity="center" android:background="@android:color/holo_green_dark" /> <RadioGroup android:id="@+id/radio_group" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_alignParentBottom="true" android:orientation="horizontal" android:background="@android:color/holo_blue_dark"/> </RelativeLayout>

RadioButton

...并为我的<?xml version="1.0" encoding="utf-8"?> <RadioButton xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="2dp" android:layout_weight="1" android:background="@android:color/darker_gray" android:button="@android:color/transparent" android:gravity="center" android:padding="10dp" />

创建了单独的_radio_button.xml_布局
RadioButton

在我的活动中,我现在以编程方式添加public class TestRadioActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create an inflater to inflate our buttons LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); // Create the layout params for our buttons LinearLayout.LayoutParams layoutParams = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f); RadioGroup group = (RadioGroup) findViewById(R.id.radio_group); // Add button one RadioButton button = (RadioButton) inflater.inflate(R.layout.radio_button, null); button.setText("Option 1"); group.addView(button, layoutParams); // Add button two button = (RadioButton) inflater.inflate(R.layout.radio_button, null); button.setText("Option 2"); group.addView(button, layoutParams); } }

RadioButton

请注意_radio_button.xml_文件和活动如何指定WRAP_CONTENT的布局宽度和布局权重1,以均匀分布按钮,如原始 main.xml

然而,布局似乎被忽略了布局权重,而按钮位于收音机组的左侧:

Radio buttons not being evenly distributed

正如其他地方所建议的那样,我也尝试在LayoutParams中将RadioButton s的宽度设置为0(显然这会导致布局权重的解释略有不同),但这会导致RadioButton甚至无法呈现:

Radio buttons missing completely

是否可以建议如何以编程方式添加RadioGroup以均匀填充包含{{1}}的整个宽度?有什么明显的我遗失了吗?

3 个答案:

答案 0 :(得分:17)

设置布局权重时,应使用fill_parent作为布局宽度。然后你不应该使用LinearLayout.LayoutParams而是RadioGroup.LayoutParams,因为你要向RadioGroup添加单选按钮,而不是简单的LinearLayout。

最后,当您使用inflater来“构建”单选按钮时,单选按钮的XML文件已经从XML文件中选择了布局参数,所以我认为您应该只调用addView方法视图添加为参数(即addView(View v))并将layout_width更改为fill_parent。

请注意,如果您需要在代码中引用变量“button”,即添加单击侦听器,则只会将侦听器添加到最后创建的按钮。你必须为你将添加到RadioGroup的每个RadioButton创建一个RadioButton对象(button,button1,button2等)。

答案 1 :(得分:9)

仅供参考,完全没有任何xml

    RadioGroup rgrp = new RadioGroup(context);
    rgrp.setLayoutParams(new RadioGroup.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
    rgrp.setOrientation(LinearLayout.HORIZONTAL);

        mAccent = new RadioButton(context);
        mAccent.setText("Accent");
        mAccent.setLayoutParams(new RadioGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
        rgrp.addView(mAccent);

        mGhost = new RadioButton(context);
        mGhost.setText( "Ghost");
        mGhost.setLayoutParams(new RadioGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
        rgrp.addView(mGhost);

        mFlam = new RadioButton(context);
        mFlam.setText( "Flam");
        mFlam.setLayoutParams(new RadioGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
        rgrp.addView(mFlam);

    layout.addView(rgrp);

答案 2 :(得分:1)

我也遇到了这个问题,我使用了RadioGroup.LayoutParams定义了权重。但是我也发现,一旦我以编程方式创建按钮,它们就不会响应触摸,因此将clickableenabled设置为true以及修复了一些内容。

  private RadioButton createMyTypeRadioButton(MyType type){

    //create using this constructor to use some of the style definitions
    RadioButton radio = new RadioButton(this, null, R.style.MyRadioStyle);

    RadioGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f);
    radio.setLayoutParams(layoutParams);
    radio.setGravity(Gravity.CENTER);

    //tag used by the setOnCheckedChangeListener to link the radio button with mytype object
    radio.setTag(type.getId());

    //enforce enabled and clickable status otherwise they ignore clicks
    radio.setClickable(true);
    radio.setEnabled(true);

    radio.setText(type.getTitle());


    return radio;
}

private void updateMyTypesUi() {

    //populate RadioGroup with permitted my types
    for (int i = 0; i < myTypes.size(); i++) {
        MyType type = myTypes.get(i);           
        RadioButton radioButton = createSwapTypeRadioButton(type);
        myRadioGrp.addView(radioButton);

    }

    myRadioGrp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            RadioButton checkedType = (RadioButton) group.findViewById(checkedId);              
            String idOfMyTypeChecked = (String) checkedType.getTag();
            //do something with idOfMyTypeChecked
        }
    });
}