如何对 3x3 的单选按钮网格进行分组?
Posted
技术标签:
【中文标题】如何对 3x3 的单选按钮网格进行分组?【英文标题】:How to group a 3x3 grid of radio buttons? 【发布时间】:2011-01-23 19:19:24 【问题描述】:正如标题所述,我正在尝试将 3x3 单选按钮的网格组合成一个单选组。在上一个问题中,我了解到单选按钮要对应于单个组,它们必须是它们将对应的单选组的直接子级。当我尝试将整个表格布局(表格行中的单选按钮)封装在一个单选组中时,我很难学到这一点。
碰到那堵墙,我尝试了以下方法:
<TableLayout android:id="@+id/table_radButtons"
android:layout_
android:layout_
android:layout_below="@+id/title_radGroup_buffer">
<TableRow>
<RadioGroup android:layout_
android:layout_
android:orientation="horizontal"
android:id="@+id/radGroup1">
<RadioButton android:id="@+id/rad1"
android:text="Button1"
android:layout_
android:layout_
android:textSize="13px"></RadioButton>
<RadioButton android:id="@+id/rad2"
android:text="Button2"
android:layout_
android:textSize="13px"
android:layout_></RadioButton>
<RadioButton android:id="@+id/rad3"
android:text="Button3"
android:layout_
android:textSize="13px"
android:layout_></RadioButton>
</RadioGroup>
</TableRow>
<TableRow>
<RadioGroup android:layout_
android:layout_
android:orientation="horizontal"
android:id="@+id/radGroup1">
<!-- snippet -->
</TableRow>
<!-- snippet --->
</TableLayout>
显然我第一次没学,因为我又撞墙了。我希望不同表格行中的单选按钮会注意到它们属于同一个单选组(为每个组提供相同的 ID),但这不起作用。
有什么方法可以将所有这些按钮组合到一个单选组中,并且仍然保持我的 3x3 结构(3 行,每行 3 个单选按钮)?
【问题讨论】:
【参考方案1】:实际上,如果你像这个例子那样子类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;
并创建一个这样的布局(当然你需要清理它,但你明白了)
<?xml version="1.0" encoding="utf-8"?>
<com.codtech.android.view.ToggleButtonGroupTableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_ android:layout_
android:id="@+id/radGroup1">
<TableRow>
<RadioButton android:id="@+id/rad1" android:text="Button1"
android:layout_ android:layout_
android:textSize="13px" />
<RadioButton android:id="@+id/rad2" android:text="Button2"
android:layout_ android:textSize="13px"
android:layout_ />
<RadioButton android:id="@+id/rad3" android:text="Button3"
android:layout_ android:textSize="13px"
android:layout_ />
</TableRow>
<TableRow>
<RadioButton android:id="@+id/rad1" android:text="Button1"
android:layout_ android:layout_
android:textSize="13px" />
<RadioButton android:id="@+id/rad2" android:text="Button2"
android:layout_ android:textSize="13px"
android:layout_ />
<RadioButton android:id="@+id/rad3" android:text="Button3"
android:layout_ android:textSize="13px"
android:layout_ />
</TableRow>
<TableRow>
<RadioButton android:id="@+id/rad1" android:text="Button1"
android:layout_ android:layout_
android:textSize="13px" />
<RadioButton android:id="@+id/rad2" android:text="Button2"
android:layout_ android:textSize="13px"
android:layout_ />
<RadioButton android:id="@+id/rad3" android:text="Button3"
android:layout_ android:textSize="13px"
android:layout_ />
</TableRow>
</com.codtech.android.view.ToggleButtonGroupTableLayout>
【讨论】:
我得看看这个,看看我能不能完全理解你在做什么。谢谢。 如何在更改时获取选中的按钮ID? 谢谢,这很好用。复制,粘贴,完成。好东西!! @dtmilano:在可能的情况下,我必须默认设置第一个单选按钮。然后你的代码不起作用。但是我注意到,如果我单击第一个单选按钮,它就会开始工作。我需要进行哪些更改才能使代码适用于我的情况? 我解决了我的问题!如果最初选中了一个单选按钮(在布局文件中),则需要在方法 setChildrenOnClickListener 中将 activeRadioButton 设置为此选中的单选按钮。【参考方案2】:在上面https://***.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];
;
并按如下方式在 XML 中使用它
<com.test.customviews.RadioGridGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad1"
android:layout_
android:layout_
android:text="Button1" />
<RadioButton
android:id="@+id/rad2"
android:layout_
android:layout_
android:text="Button2" />
</TableRow>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad3"
android:layout_
android:layout_
android:text="Button3" />
<RadioButton
android:id="@+id/rad4"
android:layout_
android:layout_
android:text="Button4" />
</TableRow>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad5"
android:layout_
android:layout_
android:text="Button5" />
<RadioButton
android:id="@+id/rad6"
android:layout_
android:layout_
android:text="Button6" />
</TableRow>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad7"
android:layout_
android:layout_
android:text="Button7" />
<RadioButton
android:id="@+id/rad8"
android:layout_
android:layout_
android:text="Button8" />
</TableRow>
</com.test.customviews.RadioGridGroup>
如有其他改进,请发表评论。
【讨论】:
在任何java包中你都可以放这个。 效果很好!但它在 xml 中有一个小错字:wrap_contact 应该是 wrap_content。 我正在尝试在运行时添加 TableRow 和 RadioButton 它正在工作,但也允许多选,有什么解决方案吗? @PriyankVadariya 我们可以做到。但是,我们需要修改解决方案 这适用于 Android 10。而 rajath 答案不适用于我的 poco x3 nfc 上的 android 10。【参考方案3】:这使用带有 RadioGroup 功能的自定义 GridLayout。谢谢 Saikrishnan Ranganathan for saiaspire/RadioGridGroup
<com.sample.RadioGridGroup
xmlns:grid="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
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>
【讨论】:
谢谢伙计。我正在使用线性布局插入该组。它显示正常,但无法正常运行。你救了我,伙计。 这在 Android Studio 中正确呈现,但在我的 POCO X3 NFC android 10 上不起作用。上面的答案与表格布局工作。【参考方案4】:我编写了一个非常简单的GridLayout
子类,其作用类似于RadioGroup
。看起来是这样的:
要使用它,首先添加GridLayout
库:
implementation "androidx.gridlayout:gridlayout:1.0.0-beta01"
然后复制粘贴GridLayout
子类:
/**
* A GridLayout subclass that acts like a RadioGroup. Important: it only accepts RadioButton as children.
* Inspired by https://***.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)
终于可以用了:
<com.example.ui.GridRadioGroup
android:id="@+id/gridRadioGroup"
android:layout_
android:layout_
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>
风格:
<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>
代码很简单,但对我来说效果很好。如果您想要更完整的东西(例如OnCheckedChangeListener
),那么check this alternative implementation 显然更精细,并且在功能方面与RadioGroup
相当。
【讨论】:
【参考方案5】:我会选择嵌套的 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>
每个子类 RadioGroups 都有一个 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);
现在只需在 switch case 中使用clearCheck()
,您就可以清除其他两个 RadioGroup 的检查。像这样:
case R.id.radioButton_1:
if (checked)
rg_2.clearCheck();
rg_3.clearCheck();
break;
【讨论】:
我发现这比这里的其他答案更简单...;D【参考方案6】:您唯一的选择是将源代码获取到RadioGroup
并尝试在TableLayout
或其他东西中复制其功能。否则无法创建RadioButtons
的 3x3 网格。幸运的是,RadioButton
类不知道RadioGroup
——所有互斥逻辑都在RadioGroup
中。因此,应该可以创建一个RadioGrid
或其他东西……但这将是一项非常艰巨的工作。
【讨论】:
所以也没有办法使用像 GridView 这样的东西? 仅当您将其子类化并赋予它 RadioGroup 功能时。【参考方案7】:RadioGroup 以下列方式扩展..
java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.widget.LinearLayout
↳ android.widget.RadioGroup
如果您需要在网格布局中排列单选按钮,您可能需要构建自己的自定义代码,该代码从 GridLayout
扩展而来。
【讨论】:
【参考方案8】:这是一个杂物,但为什么不使用九个 RadioGroup 或三个水平 RadioGroup,每个 RadioGroup 有三个按钮。然后可以将每个单选组与 gridView 或 relativeLayout 等对齐。
然后不使用 RadioButton 的标准 OnCheckedChangeListener,而是使用属于 CompoundButton 的(同名)。
然后,每当按下任何 RadioButton 时,您都可以使用单选组取消选择单选按钮。然后以编程方式选择被单击的单选按钮。
这是一个可怕的解决方案,但它的工作原理正如人们所希望的那样。
下面是一些示例代码,我使用 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);
【讨论】:
【参考方案9】:在我看来,一个更简单的方法是使用RecyclerView
。ViewHolder
将只包含一个 RadioButton
。data class
将包含要显示的 string
属性,以及用于切换 isChecked
状态的附加 boolean
属性。
在ViewHolder
内部,我们将在onClickListener
内部切换状态。RecyclerViewAdapter
将包含一个额外的函数来获取所选项目。
代码示例
血型.kt
data class BloodType(val name: String, var isChecked: Boolean)
item_blood_type.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_>
<RadioButton
android:id="@+id/rb_item_blood_type"
android:layout_
android:layout_
tools:text="RadioButton"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
BloodTypeAdapter.kt
class BloodTypeAdapter(val data: List<BloodType>) :
RecyclerView.Adapter<BloodTypeAdapter.BloodTypeHolder>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BloodTypeHolder
val view =
LayoutInflater.from(parent.context).inflate(R.layout.item_blood_type, parent, false)
return BloodTypeHolder(view)
override fun onBindViewHolder(holder: BloodTypeHolder, position: Int)
holder.itemView.rb_item_blood_type.isChecked = data[position].isChecked
holder.itemView.rb_item_blood_type.text = data[position].name
override fun getItemCount(): Int
return data.size
/**
* @return The selected item from the list.
*/
fun getCheckedItem(): BloodType
data.forEach
if (it.isChecked)
return it
return data[0]
inner class BloodTypeHolder(view: View) : RecyclerView.ViewHolder(view)
init
itemView.rb_item_blood_type.setOnClickListener
data.forEachIndexed index, bloodType ->
bloodType.isChecked = index == adapterPosition
notifyDataSetChanged()
Presenter.kt
//...
private fun initializeBloodTypeRecyclerView()
rvBloodType.layoutManager = GridLayoutManager(context, 2)
val bloodTypes = mutableListOf<BloodType>()
bloodTypes.apply
add(BloodType("A+", true))
add(BloodType("A-", false))
add(BloodType("B+", false))
//...
val bloodTypeAdapter = BloodTypeAdapter(bloodTypes)
rvBloodType.adapter = bloodTypeAdapter
//...
【讨论】:
【参考方案10】:这里是解决方案
public class RadioGridGroup extends TableLayout implements View.OnClickListener
private static final String TAG = "ToggleButtonGroupTableLayout";
private int checkedButtonID = -1;
private RadioGridGroup.OnCheckedChangeListener mOnCheckedChangeListener;
/**
* @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)
if (mOnCheckedChangeListener != null)
mOnCheckedChangeListener.onCheckedChanged(this, 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];
;
public void setOnCheckedChangeListener(RadioGridGroup.OnCheckedChangeListener listener)
mOnCheckedChangeListener = listener;
public interface OnCheckedChangeListener
public void onCheckedChanged(RadioGridGroup group, @IdRes int checkedId);
点击监听器
RadioGridGroup radioGroup = findViewById(R.id.radioGroup);
radioGroup.setOnCheckedChangeListener(new RadioGridGroup.OnCheckedChangeListener()
@Override
public void onCheckedChanged(RadioGridGroup group, int checkedId)
if (checkedId == R.id.radio6)
);
XML
<com.customviews.RadioGridGroup
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad1"
android:layout_
android:layout_
android:text="Button1" />
<RadioButton
android:id="@+id/rad2"
android:layout_
android:layout_
android:text="Button2" />
</TableRow>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad3"
android:layout_
android:layout_
android:text="Button3" />
<RadioButton
android:id="@+id/rad4"
android:layout_
android:layout_
android:text="Button4" />
</TableRow>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad5"
android:layout_
android:layout_
android:text="Button5" />
<RadioButton
android:id="@+id/rad6"
android:layout_
android:layout_
android:text="Button6" />
</TableRow>
<TableRow android:layout_marginTop="@dimen/preview_five">
<RadioButton
android:id="@+id/rad7"
android:layout_
android:layout_
android:text="Button7" />
<RadioButton
android:id="@+id/rad8"
android:layout_
android:layout_
android:text="Button8" />
</TableRow>
</com.customviews.RadioGridGroup>
注意:确保所有单选按钮都必须在 TableRow 下。
【讨论】:
以上是关于如何对 3x3 的单选按钮网格进行分组?的主要内容,如果未能解决你的问题,请参考以下文章