Java 如何对单选按钮的 3x3 网格进行分组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2381560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:47:40  来源:igfitidea点击:

How to group a 3x3 grid of radio buttons?

javaandroidxml

提问by Fizz

As the title describes, I'm trying to group up a grid of 3x3 radio buttons into a single radio group. In a previous question asked I learned that for radio buttons to correspond to a single group they had to be the immediate children of the radio group to which they will correspond. I learned this the hard way when I attempted to encapsulate an entire table layout (with the radio buttons in the table rows) in a radio group.

正如标题所描述的,我试图将一个 3x3 单选按钮的网格分组到一个单选组中。在上一个问题中,我了解到要使单选按钮与单个组对应,它们必须是它们将对应的单选组的直接子项。当我试图将整个表格布局(表格行中的单选按钮)封装在一个单选组中时,我学到了这一点。

Running into that wall, I tried the following:

跑到那堵墙上,我尝试了以下方法:

<TableLayout android:id="@+id/table_radButtons" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_below="@+id/title_radGroup_buffer">

        <TableRow>
            <RadioGroup android:layout_width="fill_parent" 
                android:layout_height="wrap_content" 
                android:orientation="horizontal"
                android:id="@+id/radGroup1">  

                <RadioButton android:id="@+id/rad1" 
                    android:text="Button1" 
                    android:layout_width="105px" 
                    android:layout_height="wrap_content" 
                    android:textSize="13px"></RadioButton>
                <RadioButton android:id="@+id/rad2" 
                    android:text="Button2" 
                    android:layout_width="105px" 
                    android:textSize="13px" 
                    android:layout_height="wrap_content"></RadioButton>
                <RadioButton android:id="@+id/rad3" 
                    android:text="Button3" 
                    android:layout_width="105px" 
                    android:textSize="13px" 
                    android:layout_height="wrap_content"></RadioButton>
            </RadioGroup>
        </TableRow>
        <TableRow>
            <RadioGroup android:layout_width="fill_parent" 
                android:layout_height="wrap_content" 
                android:orientation="horizontal"
                android:id="@+id/radGroup1">
                  <!-- snippet -->
        </TableRow>
        <!-- snippet --->
</TableLayout>

Obviously I didn't learn the first time because I ran into a wall again. I was hoping that the radio buttons in different table rows would notice that they were part of the same radio group (gave each group the same ID) but this didn't work.

显然我第一次没有学到,因为我又撞到了墙。我希望不同表格行中的单选按钮会注意到它们属于同一个单选组(为每个组提供相同的 ID),但这不起作用。

Is there any way I can group all of these buttons into a single radio group and still maintain my 3x3 structure (3 rows, 3 radio buttons in each row)?

有什么办法可以将所有这些按钮分组到一个单选组中,并且仍然保持我的 3x3 结构(3 行,每行 3 个单选按钮)?

采纳答案by Diego Torres Milano

Actually it's not that hard if you subclass TableLayoutlike in this example

实际上,如果你TableLayout像在这个例子中那样子类化,这并不难

/**
 * 
 */
package com.codtech.android.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RadioButton;
import android.widget.TableLayout;
import android.widget.TableRow;

/**
 * @author diego
 *
 */
public class ToggleButtonGroupTableLayout extends TableLayout  implements OnClickListener {

    private static final String TAG = "ToggleButtonGroupTableLayout";
    private RadioButton activeRadioButton;

    /** 
     * @param context
     */
    public ToggleButtonGroupTableLayout(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param context
     * @param attrs
     */
    public ToggleButtonGroupTableLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onClick(View v) {
        final RadioButton rb = (RadioButton) v;
        if ( activeRadioButton != null ) {
            activeRadioButton.setChecked(false);
        }
        rb.setChecked(true);
        activeRadioButton = rb;
    }

    /* (non-Javadoc)
     * @see android.widget.TableLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams)
     */
    @Override
    public void addView(View child, int index,
            android.view.ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
        setChildrenOnClickListener((TableRow)child);
    }


    /* (non-Javadoc)
     * @see android.widget.TableLayout#addView(android.view.View, android.view.ViewGroup.LayoutParams)
     */
    @Override
    public void addView(View child, android.view.ViewGroup.LayoutParams params) {
        super.addView(child, params);
        setChildrenOnClickListener((TableRow)child);
    }


    private void setChildrenOnClickListener(TableRow tr) {
        final int c = tr.getChildCount();
        for (int i=0; i < c; i++) {
            final View v = tr.getChildAt(i);
            if ( v instanceof RadioButton ) {
                v.setOnClickListener(this);
            }
        }
    }

    public int getCheckedRadioButtonId() {
        if ( activeRadioButton != null ) {
            return activeRadioButton.getId();
        }

        return -1;
    }
}

and create a layout like this (of course you need to clean it up but you got the idea)

并创建这样的布局(当然你需要清理它,但你有想法)

<?xml version="1.0" encoding="utf-8"?>
<com.codtech.android.view.ToggleButtonGroupTableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:id="@+id/radGroup1">
    <TableRow>
            <RadioButton android:id="@+id/rad1" android:text="Button1"
                android:layout_width="105px" android:layout_height="wrap_content"
                android:textSize="13px" />
            <RadioButton android:id="@+id/rad2" android:text="Button2"
                android:layout_width="105px" android:textSize="13px"
                android:layout_height="wrap_content" />
            <RadioButton android:id="@+id/rad3" android:text="Button3"
                android:layout_width="105px" android:textSize="13px"
                android:layout_height="wrap_content" />
    </TableRow>
    <TableRow>
            <RadioButton android:id="@+id/rad1" android:text="Button1"
                android:layout_width="105px" android:layout_height="wrap_content"
                android:textSize="13px" />
            <RadioButton android:id="@+id/rad2" android:text="Button2"
                android:layout_width="105px" android:textSize="13px"
                android:layout_height="wrap_content" />
            <RadioButton android:id="@+id/rad3" android:text="Button3"
                android:layout_width="105px" android:textSize="13px"
                android:layout_height="wrap_content" />
    </TableRow>
    <TableRow>
            <RadioButton android:id="@+id/rad1" android:text="Button1"
                android:layout_width="105px" android:layout_height="wrap_content"
                android:textSize="13px" />
            <RadioButton android:id="@+id/rad2" android:text="Button2"
                android:layout_width="105px" android:textSize="13px"
                android:layout_height="wrap_content" />
            <RadioButton android:id="@+id/rad3" android:text="Button3"
                android:layout_width="105px" android:textSize="13px"
                android:layout_height="wrap_content" />
    </TableRow>
</com.codtech.android.view.ToggleButtonGroupTableLayout>

回答by CommonsWare

Your only option is to grab the source code to RadioGroupand attempt to replicate its functionality in a TableLayoutor something. There is no way to create a 3x3 grid of RadioButtonsotherwise. Fortunately, the RadioButtonclass does not know about RadioGroup-- all of the mutual-exclusion logic is in RadioGroup. Hence, it should be possible to create a RadioGridor something...but that's going to be an awful lot of work.

您唯一的选择是获取源代码RadioGroup并尝试在 aTableLayout或其他东西中复制其功能。RadioButtons否则无法创建 3x3 网格。幸运的是,RadioButton该类不知道RadioGroup——所有的互斥逻辑都在RadioGroup. 因此,应该有可能创建一个RadioGrid或其他东西......但这将是大量的工作。

回答by Rupin

RadioGroup extends in the following manner..

RadioGroup 以下列方式扩展..

java.lang.Object
 ?  android.view.View
   ?    android.view.ViewGroup
       ?    android.widget.LinearLayout
           ?    android.widget.RadioGroup

If you need to arrange the radio button in a grid layout, you might need to build you own custom code that extends from GridLayout.

如果您需要在网格布局中排列单选按钮,您可能需要构建您自己的自定义代码,从GridLayout.

回答by Andrew S

It's a cludge but why not Why not just use nine RadioGroups, or three horizontal RadioGroups each with three buttons. Each radio group can then be aligned with a gridView, or relativeLayout etc.

这是一个混乱,但为什么不为什么不使用九个 RadioGroups 或三个水平 RadioGroups,每个 RadioGroups 有三个按钮。然后每个无线电组都可以与 gridView 或 relativeLayout 等对齐。

The then instead of using the standard OnCheckedChangeListener of RadioButton use the one (of the same name) belonging to the CompoundButton instead.

然后,不是使用 RadioButton 的标准 OnCheckedChangeListener,而是使用属于 CompoundButton 的(同名)。

Then when ever any RadioButton is pressed you can use the radio groups to deselect the radio buttons. Then programmatically select the radio button that was clicked.

然后,当按下任何 RadioButton 时,您可以使用单选组取消选择单选按钮。然后以编程方式选择单击的单选按钮。

It's a horrible solution, but it works as one would hope it to.

这是一个可怕的解决方案,但它正如人们所希望的那样工作。

Below is some example code I used to do this with a 2x2 layout of buttons.

下面是一些示例代码,我用 2x2 的按钮布局来做到这一点。

  public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        updateList(Hurricane.ELEVATION_ALL);

        watermarkAdapter = new WatermarkAdapter(getActivity(), R.layout.watermark_item, 
                           relatedHurricanes);

        setListAdapter(watermarkAdapter);

        this.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        this.getView().setBackgroundResource(R.drawable.splash_screen1);


        getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);


        View v = this.getView();
        filterGroup1 = (RadioGroup)v.findViewById(R.id.filter_rg1);
        filterGroup2 = (RadioGroup)v.findViewById(R.id.filter_rg2);
        filterGroup3 = (RadioGroup)v.findViewById(R.id.filter_rg3);
        filterGroup4 = (RadioGroup)v.findViewById(R.id.filter_rg4);


        rb1 = (RadioButton) v.findViewById(R.id.first_radio_button);//All
        rb2 = (RadioButton) v.findViewById(R.id.second_radio_button);//0-6
        rb4 = (RadioButton) v.findViewById(R.id.third_radio_button);//6-12
        rb3 = (RadioButton) v.findViewById(R.id.fourth_radio_button);//>=5

        rb1.setOnCheckedChangeListener(this);
        rb2.setOnCheckedChangeListener(this);
        rb3.setOnCheckedChangeListener(this);
        rb4.setOnCheckedChangeListener(this);


    }






 @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

        filterGroup1.clearCheck();
        filterGroup2.clearCheck();
        filterGroup3.clearCheck();
        filterGroup4.clearCheck();


        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(this.getActivity());

       int cid = buttonView.getId();

       Editor editor     = prefs.edit();
       int elevation = Hurricane.ELEVATION_ALL;
        //All
       if(rb1.getId() == cid){
          elevation = Hurricane.ELEVATION_ALL;
       }  
       //0-6
       else if(rb2.getId() == cid){
           elevation = Hurricane.ELEVATION_6to12;
       }
       //6-12
       else if(rb3.getId() == cid){       
           elevation = Hurricane.ELEVATION_0to6;
       }
       //>=12
       else if(rb4.getId() == cid){
           elevation = Hurricane.ELEVATION_GT12;
       }

       update(StormFragment.NORMAL, elevation);

    }

回答by Nigam Patro

After above https://stackoverflow.com/a/2383978/5567009answer I got another solution for this question, I added some other functionality like, to save the state of the group and also functionality to clear the check functionality like in radio group.

在上面的https://stackoverflow.com/a/2383978/5567009回答之后我得到了这个问题的另一个解决方案,我添加了一些其他功能,例如保存组的状态以及清除检查功能的功能,例如无线电组.

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IdRes;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RadioButton;
import android.widget.TableLayout;
import android.widget.TableRow;

public class RadioGridGroup extends TableLayout implements View.OnClickListener {

    private static final String TAG = "ToggleButtonGroupTableLayout";
    private int checkedButtonID = -1;

    /**
     * @param context
     */
    public RadioGridGroup(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param context
     * @param attrs
     */
    public RadioGridGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onClick(View v) {
        if (v instanceof RadioButton) {
            int id = v.getId();
            check(id);
        }
    }

    private void setCheckedStateForView(int viewId, boolean checked) {
        View checkedView = findViewById(viewId);
        if (checkedView != null && checkedView instanceof RadioButton) {
            ((RadioButton) checkedView).setChecked(checked);
        }
    }

    /* (non-Javadoc)
     * @see android.widget.TableLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams)
     */
    @Override
    public void addView(View child, int index,
                        android.view.ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
        setChildrenOnClickListener((TableRow) child);
    }


    /* (non-Javadoc)
     * @see android.widget.TableLayout#addView(android.view.View, android.view.ViewGroup.LayoutParams)
     */
    @Override
    public void addView(View child, android.view.ViewGroup.LayoutParams params) {
        super.addView(child, params);
        setChildrenOnClickListener((TableRow) child);
    }


    private void setChildrenOnClickListener(TableRow tr) {
        final int c = tr.getChildCount();
        for (int i = 0; i < c; i++) {
            final View v = tr.getChildAt(i);
            if (v instanceof RadioButton) {
                v.setOnClickListener(this);
            }
        }
    }


    /**
     * @return the checked button Id
     */
    public int getCheckedRadioButtonId() {
        return checkedButtonID;
    }


    /**
     * Check the id
     *
     * @param id
     */
    public void check(@IdRes int id) {
        // don't even bother
        if (id != -1 && (id == checkedButtonID)) {
            return;
        }
        if (checkedButtonID != -1) {
            setCheckedStateForView(checkedButtonID, false);
        }
        if (id != -1) {
            setCheckedStateForView(id, true);
        }
        setCheckedId(id);
    }

    /**
     * set the checked button Id
     *
     * @param id
     */
    private void setCheckedId(int id) {
        this.checkedButtonID = id;
    }

    public void clearCheck() {
        check(-1);
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }

        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());

        this.checkedButtonID = ss.buttonId;
        setCheckedStateForView(checkedButtonID, true);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState savedState = new SavedState(superState);
        savedState.buttonId = checkedButtonID;
        return savedState;
    }

    static class SavedState extends BaseSavedState {
        int buttonId;

        /**
         * Constructor used when reading from a parcel. Reads the state of the superclass.
         *
         * @param source
         */
        public SavedState(Parcel source) {
            super(source);
            buttonId = source.readInt();
        }

        /**
         * Constructor called by derived classes when creating their SavedState objects
         *
         * @param superState The state of the superclass of this view
         */
        public SavedState(Parcelable superState) {
            super(superState);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeInt(buttonId);
        }

        public static final Parcelable.Creator<SavedState> CREATOR =
                new Parcelable.Creator<SavedState>() {
                    public SavedState createFromParcel(Parcel in) {
                        return new SavedState(in);
                    }

                    public SavedState[] newArray(int size) {
                        return new SavedState[size];
                    }
                };
    }
}

and use this in XML as follows

并在 XML 中使用它,如下所示

<com.test.customviews.RadioGridGroup xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TableRow android:layout_marginTop="@dimen/preview_five">

        <RadioButton
            android:id="@+id/rad1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button1" />

        <RadioButton
            android:id="@+id/rad2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button2" />
    </TableRow>

    <TableRow android:layout_marginTop="@dimen/preview_five">

        <RadioButton
            android:id="@+id/rad3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button3" />

        <RadioButton
            android:id="@+id/rad4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button4" />
    </TableRow>

    <TableRow android:layout_marginTop="@dimen/preview_five">

        <RadioButton
            android:id="@+id/rad5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button5" />

        <RadioButton
            android:id="@+id/rad6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button6" />
    </TableRow>

    <TableRow android:layout_marginTop="@dimen/preview_five">

        <RadioButton
            android:id="@+id/rad7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button7" />

        <RadioButton
            android:id="@+id/rad8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button8" />
    </TableRow>
</com.test.customviews.RadioGridGroup>

For any other improvements, please comment.

对于任何其他改进,请发表评论。

回答by dcx86

I for one would go for nested RadioGroups. The Root RadioGroup will have a Vertical orientation and its children will be three RadioGroups with Horizontal orientation.

我会选择嵌套的 RadioGroups。根 RadioGroup 将具有垂直方向,其子项将是三个具有水平方向的 RadioGroup。

<RadioGroup
    android:orientation="vertical">
    <RadioGroup
        android:id="@+id/rg_1"
        android:orientation="horizontal">
        <RadioButton />
        <RadioButton />
        <RadioButton />
    </RadioGroup>
    <RadioGroup
        android:id="@id/rg_2"
        android:orientation="horizontal">
        <RadioButton />
        <RadioButton />
        <RadioButton />
    </RadioGroup>
    <RadioGroup
        android:id="@+id/rg_3"
        android:orientation="horizontal">
        <RadioButton />
        <RadioButton />
        <RadioButton />
    </RadioGroup>
</RadioGroup>

Each of the chield RadioGroups will have an ID which will be called by a RadioGroup object inside the java validation method. Like this:

每个子 RadioGroup 都有一个 ID,该 ID 将由 Java 验证方法中的 RadioGroup 对象调用。像这样:

RadioGroup rg_1 = (RadioGroup) findViewById(R.id.rg_1);
RadioGroup rg_2 = (RadioGroup) findViewById(R.id.rg_2);
RadioGroup rg_3 = (RadioGroup) findViewById(R.id.rg_3);

Now simply by using clearCheck()inside the switch case you can clear the check of the other two RadioGroups. Like this:

现在只需clearCheck()在 switch case 中使用,您就可以清除其他两个 RadioGroup 的检查。像这样:

case R.id.radioButton_1:
            if (checked) {
                rg_2.clearCheck();
                rg_3.clearCheck();
            }
            break;

回答by rajath

This uses a custom GridLayout with the RadioGroup functionality. Thanks to Saikrishnan Ranganathan for saiaspire/RadioGridGroup

这使用具有 RadioGroup 功能的自定义 GridLayout。感谢 Saikrishnan Ranganathan 的 saiaspire/RadioGridGroup

<com.sample.RadioGridGroup
        xmlns:grid="http://schemas.android.com/apk/res-auto"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        grid:columnCount="3"
        grid:useDefaultMargins="true">

        <android.support.v7.widget.AppCompatRadioButton
            android:checked="true"
            android:text="Text1"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text2"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text3"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text4"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text5"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text6"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text7"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text8"
            grid:layout_columnWeight="1"/>

        <android.support.v7.widget.AppCompatRadioButton
            android:text="Text9"
            grid:layout_columnWeight="1"/>

    </com.sample.RadioGridGroup>

回答by Albert Vila Calvo

I've written a very simple GridLayoutsubclass that acts like a RadioGroup. This is how it looks:

我编写了一个非常简单的GridLayout子类,它的作用类似于RadioGroup. 这是它的外观:

GridLayout RadioGroup with RadioButton

带有 RadioButton 的 GridLayout RadioGroup

To use it first add the GridLayoutlibrary:

要使用它首先添加GridLayout库:

implementation "androidx.gridlayout:gridlayout:1.0.0-beta01"

Then copy-paste the GridLayoutsubclass:

然后复制粘贴GridLayout子类:

**
 * A GridLayout subclass that acts like a RadioGroup. Important: it only accepts RadioButton as children.
 * Inspired by https://stackoverflow.com/a/2383978/4034572
 */
class GridRadioGroup @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : GridLayout(context, attrs, defStyleAttr), View.OnClickListener {

    @IdRes var selectedRadioButtonId: Int? = null
    get() = getSelectedRadioButton()?.id
    private set

    private fun getSelectedRadioButton(): RadioButton? {
        for (index in 0 until childCount) {
            val radioButton = getChildAt(index) as RadioButton
            if (radioButton.isChecked) return radioButton
        }
        return null
    }

    override fun onClick(view: View) {
        // While this looks inefficient, it does fix a bug (2 RadioButtons could be selected at the
        // same time) when navigating back by popping-up a fragment from the backstack.
        for (index in 0 until childCount) {
            val radioButton = getChildAt(index) as RadioButton
            radioButton.isChecked = false
        }
        val radioButton = view as RadioButton
        radioButton.isChecked = true
    }

    override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
        super.addView(child, index, params)
        child?.setOnClickListener(this)
    }

}

Finally just use it:

最后只需使用它:

<com.example.ui.GridRadioGroup
    android:id="@+id/gridRadioGroup"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:columnCount="2"
    >

    <RadioButton
        android:id="@+id/option_1"
        style="@style/GridRadioButton"
        android:drawableTop="@drawable/option_1"
        android:text="@string/register_choose_goal_option_1"
        app:layout_columnWeight="1"
        app:layout_rowWeight="1"
        />

    <RadioButton
        android:id="@+id/option_2"
        style="@style/GridRadioButton"
        android:drawableTop="@drawable/option_2"
        android:text="@string/option_2"
        app:layout_columnWeight="1"
        app:layout_rowWeight="1"
        tools:checked="true"
        />

    <RadioButton
        android:id="@+id/option_3"
        style="@style/GridRadioButton"
        android:drawableTop="@drawable/option_3"
        android:text="@string/option_3"
        app:layout_columnWeight="1"
        app:layout_rowWeight="1"
        tools:checked="true"
        />

    <RadioButton
        android:id="@+id/option_4"
        style="@style/GridRadioButton"
        android:drawableTop="@drawable/preparar_carrera"
        android:text="@string/option_4"
        app:layout_columnWeight="1"
        app:layout_rowWeight="1"
        />

</com.example.ui.GridRadioGroup>

The style:

样式:

<style name="GridRadioButton">
    <item name="android:layout_width">0dp</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_margin">10dp</item>
    <item name="android:background">@drawable/button_option_background_selector</item>
    <item name="android:drawablePadding">16dp</item>
    <item name="android:button">@null</item>
    <item name="android:gravity">center_horizontal</item>
    <item name="android:padding">20dp</item>
    <item name="android:textColor">@drawable/text_button_option_color_selector</item>
    <item name="android:textSize">14sp</item>
</style>

The code is simple but it's working fine for me. If you want something more complete(with for example an OnCheckedChangeListener) then check this alternative implementationwhich is clearly more elaborate and on par feature-wise with a RadioGroup.

代码很简单,但对我来说很好用。如果您想要更完整的东西(例如 an OnCheckedChangeListener),请检查这个替代实现,它显然更复杂,并且与 a 具有相同的功能RadioGroup