[英]How to group a 3x3 grid of radio buttons?
正如標題所描述的,我試圖將一個 3x3 單選按鈕的網格分組到一個單選組中。 在上一個問題中,我了解到要使單選按鈕與單個組對應,它們必須是它們將對應的單選組的直接子項。 當我試圖將整個表格布局(表格行中的單選按鈕)封裝在一個單選組中時,我學到了這一點。
跑到那堵牆上,我嘗試了以下方法:
<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>
顯然我第一次沒有學到,因為我又撞到了牆。 我希望不同表格行中的單選按鈕會注意到它們屬於同一個單選組(為每個組提供相同的 ID),但這不起作用。
有什么辦法可以將所有這些按鈕分組到一個單選組中,並且仍然保持我的 3x3 結構(3 行,每行 3 個單選按鈕)?
實際上,如果您像本示例中那樣對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_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>
在上面的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];
}
};
}
}
並在 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>
對於任何其他改進,請發表評論。
這使用具有 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>
我編寫了一個非常簡單的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://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)
}
}
最后只需使用它:
<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>
樣式:
<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
),那么檢查這個替代實現,它顯然更復雜,並且與RadioGroup
。
我會選擇嵌套的 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>
每個子 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);
現在只需在 switch case 中使用clearCheck()
就可以清除其他兩個 RadioGroup 的檢查。 像這樣:
case R.id.radioButton_1:
if (checked) {
rg_2.clearCheck();
rg_3.clearCheck();
}
break;
您唯一的選擇是獲取RadioGroup
的源代碼並嘗試在TableLayout
或其他東西中復制其功能。 否則無法創建 3x3 的RadioButtons
網格。 幸運的是, RadioButton
類不知道RadioGroup
—— 所有的互斥邏輯都在RadioGroup
。 因此,應該可以創建一個RadioGrid
或其他東西……但這將是一項RadioGrid
的工作。
RadioGroup 以下列方式擴展..
java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.widget.LinearLayout
↳ android.widget.RadioGroup
如果您需要在網格布局中排列單選按鈕,您可能需要構建您自己的自定義代碼,這些代碼從GridLayout
擴展而來。
這是一個混亂,但為什么不為什么不使用九個 RadioGroups 或三個水平 RadioGroups,每個 RadioGroups 有三個按鈕。 然后每個單選組都可以與 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);
}
我認為一個更簡單的方法是使用RecyclerView
。
ViewHolder
將只包含一個RadioButton
。
data class
將包含要顯示的string
屬性,以及用於切換isChecked
狀態的附加boolean
屬性。
里面ViewHolder
,我們將切換內部狀態onClickListener
。
RecyclerViewAdapter
將包含一個附加函數來獲取所選項目。
data class BloodType(val name: String, var isChecked: Boolean)
<?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_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/rb_item_blood_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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>
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()
}
}
}
}
//...
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
}
//...
這是解決方案
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_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.customviews.RadioGridGroup>
注意:確保所有單選按鈕都必須在 TableRow 下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.