【问题标题】:Programmatically-added RadioButtons refuse to obey LayoutParams weighting以编程方式添加的 RadioButtons 拒绝服从 LayoutParams 加权
【发布时间】:2012-02-15 22:43:11
【问题描述】:

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

做什么工作

我从一个基于RelativeLayout 的简单布局开始,它在底部包含一个大的TextView 和一个RadioGroup

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>

在运行时产生以下布局:

您可以看到android:layout_width="wrap_content"android:layout_weight="1"RadioButtons 中的使用会拉伸它们以均匀地填充封闭RadioGroup 的一半。到目前为止一切顺利。

什么不起作用

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

为了实现这一点,我从 main.xml 布局中删除了 RadioButtons:

<?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 创建了一个单独的 _radio_button.xml_ 布局:

<?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" />

在我的活动中,我现在以编程方式添加RadioButtons:

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

    }
}

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

但是,布局似乎被渲染忽略了布局权重,按钮位于单选组的左侧:

正如其他地方所建议的那样,我还尝试将LayoutParams 中的RadioButtons 的宽度设置为0(显然这会导致对布局权重的解释略有不同),但这会导致RadioButton s 甚至没有被渲染:

如果以编程方式添加RadioButtons,是否可以建议如何均匀填充包含RadioGroup 的整个宽度?我有什么明显的遗漏吗?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢。更改为 RadioGroup.LayoutParams 修复了它 - 我没有意识到它是可用的。
    • 为什么我必须明确指定参数而不是尊重我的 xml 参数?为什么这不像其他地方一样,要求我将 layout_width 设置为 0dp 才能使权重起作用?
    【解决方案2】:

    仅供参考,完全不需要任何 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);
    

    【讨论】:

    • 通过将父级匹配到无线电组的宽度可以正常工作。
    【解决方案3】:

    我也遇到了这个问题,我使用了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
            }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2017-08-14
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 2017-01-17
      • 2012-07-13
      • 2018-07-08
      相关资源
      最近更新 更多