¿Cómo agrupar una cuadrícula de 3×3 de botones de radio?

Como el título describe, estoy tratando de agrupar una cuadrícula de 3×3 botones de radio en un solo grupo de radio. En una pregunta anterior he preguntado que para que los botones de radio correspondieran a un solo grupo tendrían que ser los hijos inmediatos del grupo de radio al que corresponderían. Aprendí esto de la manera más difícil cuando intenté encapsular un diseño de tabla completo (con los botones de opción en las filas de la tabla) en un grupo de radio.

Corriendo en esa pared, he intentado lo siguiente:

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

Obviamente no aprendí la primera vez porque me encontré de nuevo con una pared. Tenía la esperanza de que los botones de radio en diferentes filas de la tabla se dan cuenta de que eran parte del mismo grupo de radio (dio a cada grupo el mismo ID), pero esto no funcionó.

¿Hay alguna manera de agrupar todos estos botones en un solo grupo de radio y mantener mi estructura 3×3 (3 filas, 3 botones de radio en cada fila)?

5 Solutions collect form web for “¿Cómo agrupar una cuadrícula de 3×3 de botones de radio?”

En realidad no es tan difícil si subclases TableLayout como en este ejemplo

 /** * */ 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; } } 

Y crear un diseño como este (por supuesto que necesita para limpiar, pero tienes la 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> 

Después de arriba https://stackoverflow.com/a/2383978/5567009 respuesta Tengo otra solución para esta pregunta, he añadido alguna otra funcionalidad como, para guardar el estado del grupo y también la funcionalidad para borrar la funcionalidad de verificación como en el grupo de radio .

 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]; } }; } } 

Y utilizar esto en XML como sigue

 <com.test.customviews.RadioGridGroup xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_contact" 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> 

Para cualquier otra mejora, por favor comente.

RadioGroup se extiende de la siguiente manera.

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

Si necesita organizar el botón de GridLayout en un diseño de cuadrícula, puede que necesite crear su propio código personalizado que se extienda desde GridLayout .

Su única opción es agarrar el código fuente a RadioGroup e intentar replicar su funcionalidad en un TableLayout o algo así. No hay manera de crear una red 3×3 de RadioButtons contrario. Afortunadamente, la clase RadioButton no conoce RadioGroup – toda la lógica de exclusión mutua está en RadioGroup . Por lo tanto, debe ser posible crear un RadioGrid o algo … pero eso va a ser un montón de trabajo.

Es un cludge, pero ¿por qué no? ¿Por qué no sólo utilizar nueve RadioGroups, o tres RadioGroups horizontal cada uno con tres botones. Cada grupo de radio puede alinearse con un gridView, o relativoLayout, etc.

El entonces, en lugar de utilizar el OnCheckedChangeListener estándar de RadioButton utilizar el (del mismo nombre) perteneciente al CompoundButton en su lugar.

Entonces, cuando se pulsa cualquier RadioButton, puede usar los grupos de radio para anular la selección de los botones de opción. A continuación, seleccione mediante programación el botón de opción al que se hizo clic.

Es una solución horrible, pero funciona como se esperaría.

A continuación se muestra un ejemplo de código que usé para hacer esto con un diseño 2×2 de botones.

  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); } 
  • Los dispositivos compatibles son extremadamente bajos
  • ¿Cómo puedo añadir una línea blanca 1px horizontal debajo del botón en un diseño relativo?
  • Los caracteres especiales no se muestran en android
  • Colocación de mi ActionBar en la parte inferior
  • Fuera de error de memoria al inflar el diseño xml simple en android
  • Cambio de imagen de Android programáticamente?
  • Nuevo en Android - Dibujo de una vista en tiempo de ejecución
  • Problema de renderizado con Android Studio 0.4.0
  • ¿Por qué no puedo definir atributos de android en el espacio de nombres predeterminado?
  • Cómo convertir el objeto de cursor en XML o JSON en android
  • Obtener elementos por nombre de etiqueta de un nodo en documento de Android (XML)?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.