【问题标题】:How to add a radio group to radio buttons inside of a table?如何将单选组添加到表格内的单选按钮?
【发布时间】:2010-03-02 06:08:14
【问题描述】:

我有多个单选按钮,我想使用表格进行布局,但也将它们包含在单个单选组中。我有以下 xml 布局:

<RadioGroup android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical"
      android:id="@+id/Group1">

    <TableLayout android:id="@+id/RadioButtons" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content">

        <TableRow>
            <RadioButton android:id="@+id/rad1" 
                android:text="RButton1" 
                android:layout_width="105px" 
                android:layout_height="wrap_content" 
                android:textSize="13px"></RadioButton>
            <RadioButton android:id="@+id/rad2" 
                android:text="RButton2" 
                android:layout_width="105px" 
                android:textSize="13px" 
                android:layout_height="wrap_content"></RadioButton>
            <RadioButton android:id="@+id/rad3" 
                android:text="RButton3" 
                android:layout_width="105px" 
                android:textSize="13px" 
                android:layout_height="wrap_content"></RadioButton>
        </TableRow>
      </TableLayout>
</RadioGroup>  

但不幸的是,表格内的单选按钮似乎忽略了它们位于 RadioGroup 标签内的事实,因此您一次可以选择多个单选按钮。我注意到,通过移除表格并只使用单选按钮,它就可以正常工作。我该如何克服呢?是否像在表内而不是在表外声明无线电组一样简单?谢谢你的帮助。

【问题讨论】:

    标签: xml android


    【解决方案1】:

    您的 RadioButton 小部件必须是 RadioGroup 的直接子级,组效果才能起作用。

    【讨论】:

    • 所以没有办法用表格来组织按钮并将它们作为单选组的一部分?
    • 仅当 RadioButton 小部件是 RadioGroup 的直接子级时。因此,您的 RadioButton 小部件需要位于表格的单个单元格中的行或列中。
    • 如果我以编程方式将每个单选按钮分配到一个组中会怎样?
    • @nobalG:RadioButtons 是通过布局还是通过 Java 代码添加为 RadioGroup 的子级并不重要。
    【解决方案2】:

    这是我的 RadioGroup/RadioButton 扩展 (SoftRadioGroup/SoftRadioButton)。 布局 XML 中不再需要 RadioGroup。您可以使用名为 group 的属性对 RadioButtons 进行分组。

    软单选按钮:

    import java.util.HashMap;
    import java.util.Random;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.RadioButton;
    
    public class SoftRadioButton extends RadioButton {
    
        private static HashMap<String, SoftRadioGroup> GROUP_MAPPINGS = new HashMap<String, SoftRadioGroup>();
        private String mGroupName;
    
        public SoftRadioButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            addToGroup(attrs);
        }
    
        public SoftRadioGroup getRadioGroup() {
            return GROUP_MAPPINGS.get(mGroupName);
        }
    
        private void addToGroup(AttributeSet attrs) {
            for (int i = 0; i < attrs.getAttributeCount(); i++) {
                if (attrs.getAttributeName(i).equals("group")) {
                    String groupName = attrs.getAttributeValue(i);
                    SoftRadioGroup group;
                    if ((group = GROUP_MAPPINGS.get(groupName)) != null) {
                        // RadioGroup already exists
                        group.addView(this);
                        setOnClickListener(group);
                        mGroupName = groupName;
    
                    } else {
                        // this is the first RadioButton in the RadioGroup
                        group = new SoftRadioGroup();
                        group.addView(this);
                        mGroupName = groupName;
                        setOnClickListener(group);
    
                        GROUP_MAPPINGS.put(groupName, group);
                    }
                    return;
                }
            }
            // group is not specified in the layout xml. Let's generate a random
            // RadioGroup
            SoftRadioGroup group = new SoftRadioGroup();
            group.addView(this);
            Random rn = new Random();
            String groupName;
            do {
                groupName = Integer.toString(rn.nextInt());
            } while (GROUP_MAPPINGS.containsKey(groupName));
            GROUP_MAPPINGS.put(groupName, group);
            mGroupName = groupName;
            setOnClickListener(group);
    
        }
    
    }
    

    SoftRadioGroup:

    import java.util.ArrayList;
    
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.RadioButton;
    
    public class SoftRadioGroup implements OnClickListener {
    
        private ArrayList<RadioButton> buttons = new ArrayList<RadioButton>();
    
        public void addView(RadioButton button) {
            buttons.add(button);
        }
    
        @Override
        public void onClick(View v) {
            for (RadioButton button : buttons) {
                button.setChecked(false);
            }
            RadioButton button = (RadioButton) v;
            button.setChecked(true);
        }
    
        public RadioButton getCheckedRadioButton() {
            for (RadioButton button : buttons) {
                if (button.isSelected())
                    return button;
            }
            return null;
        }
    
        public int getChildCount() {
            return buttons.size();
        }
    
        public RadioButton getChildAt(int i) {
            return buttons.get(i);
        }
    
        public void check(SoftRadioButton button) {
            if (buttons.contains(button)) {
                for (RadioButton b : buttons) {
                    b.setChecked(false);
                }
            }
        }
    
    }
    

    在嵌入在表格中的 XML 布局中的使用(2 组,每组 2 个按钮):

    <TableLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:stretchColumns="1" >
    
                <TableRow
                    android:id="@+id/tableRow1"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" >
    
                    <Your.Package.SoftRadioButton
                        android:id="@+id/filterActivity_RadioButton_byDate"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:checked="true"
                        android:contentDescription="date"
                        android:text="@string/filterActivity_RadioButton_byDate"
                        fake:group="orderBy" />
    
                    <Your.Package.SoftRadioButton
                        android:id="@+id/filterActivity_RadioButton_byPrice"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:contentDescription="price"
                        android:text="@string/filterActivity_RadioButton_byPrice"
                        fake:group="orderBy" />
                </TableRow>
    
                <TableRow
                    android:id="@+id/tableRow2"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" >
    
                    <Your.Package.SoftRadioButton
                        android:id="@+id/filterActivity_RadioButton_asc"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:contentDescription="down"
                        android:text="@string/filterActivity_RadioButton_asc"
                        fake:group="direction" />
    
                    <Your.Package.SoftRadioButton
                        android:id="@+id/filterActivity_RadioButton_desc"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:checked="true"
                        android:contentDescription="up"
                        android:text="@string/filterActivity_RadioButton_desc"
                        fake:group="direction" />
                </TableRow>
            </TableLayout>
    

    【讨论】:

    • 警告:代码会泄露视图。每次创建视图时,它都会将所有 SoftRadioButton 视图添加到静态地图中。使用自定义视图解决问题是一个好主意。我很好的解决方案可能是将 ViewGroup 添加到视图层次结构的根目录中,让它找到所有子视图并将它们配对成组。
    • 通过添加 attr.xml 修复属性 'group':,并在 xml-layout 中导入 xmlns:fake="schemas.android.com/apk/res-auto"
    • 内存泄漏的快速修复:将 onDetachedFromWindow() 方法添加到 SoftRadioButton 并调用 GROUP_MAPPINGS.remove(mGroupName);
    • 这非常有用,我添加了一个新的构造函数,将组名作为字符串,以便能够动态创建这些。
    【解决方案3】:
    rg1 = (RadioGroup)findViewById(R.id.radioGroup1);
            rg2 = (RadioGroup)findViewById(R.id.radioGroup2);
            rg1.setOnCheckedChangeListener(this);
            rg2.setOnCheckedChangeListener(this);
        }
        boolean rg1b = false;
        boolean rg2b = false;
    
        @Override
        public void onCheckedChanged(RadioGroup rgId, int radioButtonId) {
            switch (rgId.getId()) {
            case R.id.radioGroup1:
                rg1b=true;
                if(rg2b)
                    rg2.clearCheck();
                break;
    
            case R.id.radioGroup2:
                rg1b=true;
                if(rg1b)
                    rg1.clearCheck();
                break;
            }
    

    【讨论】:

    • 请不要只转储代码作为您的答案。一个解释会很有用。
    猜你喜欢
    • 2012-05-20
    • 2016-07-10
    • 2011-06-05
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 2020-09-02
    相关资源
    最近更新 更多