Comme le titre le décrit, j'essaie de regrouper une grille de boutons radio 3x3 dans un seul groupe de radio. Dans une question précédente, j'avais appris que pour que les boutons radio correspondent à un seul groupe, ils devaient être les enfants immédiats du groupe radio auquel ils correspondraient. J'ai appris cela à la dure lorsque j'ai tenté d'encapsuler toute une structure de tableau (avec les boutons radio dans les rangées du tableau) dans un groupe de radio.
En courant dans ce mur, j'ai essayé ce qui suit:
<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>
Évidemment, je n'ai pas appris la première fois parce que je me suis encore heurté à un mur. J'espérais que les boutons radio des différentes lignes de la table remarqueraient qu'ils faisaient partie du même groupe radio (attribuent le même identifiant à chaque groupe), mais cela ne fonctionnait pas.
Est-il possible de regrouper tous ces boutons dans un seul groupe de radio tout en maintenant ma structure 3x3 (3 rangées, 3 boutons radio dans chaque rangée)?
En réalité, ce n'est pas si difficile si vous sous-classe TableLayout
comme dans cet exemple
/**
*
*/
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;
}
}
et créez une mise en page comme celle-ci (bien sûr, vous devez la nettoyer, mais vous avez eu l'idée)
<?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>
Après ci-dessus https://stackoverflow.com/a/2383978/5567009 answer J'ai eu une autre solution pour cette question, j'ai ajouté d'autres fonctionnalités telles que, pour enregistrer l'état du groupe et également pour effacer la fonctionnalité de vérification comme dans un groupe 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];
}
};
}
}
et utilise ceci en XML comme suit
<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>
Pour toute autre amélioration, veuillez commenter.
Votre seule option est de récupérer le code source à RadioGroup
et d'essayer de répliquer ses fonctionnalités dans un TableLayout
ou quelque chose du genre. Sinon, il est impossible de créer une grille 3x3 de RadioButtons
. Heureusement, la classe RadioButton
ne connaît pas RadioGroup
- toute la logique d’exclusion mutuelle est dans RadioGroup
. Par conséquent, il devrait être possible de créer un RadioGrid
ou quelque chose comme ça ... mais cela va demander beaucoup de travail.
RadioGroup s'étend de la manière suivante.
Java.lang.Object
↳ Android.view.View
↳ Android.view.ViewGroup
↳ Android.widget.LinearLayout
↳ Android.widget.RadioGroup
Si vous devez organiser le bouton radio dans une disposition de grille, vous devrez peut-être créer votre propre code personnalisé qui s'étend de GridLayout
.
Pour ma part, j'irais pour RadioGroups imbriqués. Le groupe radio de base aura une orientation verticale et ses enfants seront trois groupes de radio avec une orientation horizontale.
<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>
Chacun des groupes radio Chield aura un identifiant qui sera appelé par un objet RadioGroup dans la méthode de validation Java. Comme ça:
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);
Maintenant, en utilisant simplement clearCheck()
à l'intérieur du boîtier du commutateur, vous pourrez effacer la vérification des deux autres RadioGroup. Comme ça:
case R.id.radioButton_1:
if (checked) {
rg_2.clearCheck();
rg_3.clearCheck();
}
break;
Pourquoi ne pas utiliser simplement neuf RadioGroupes, ou trois RadioGroupes horizontaux, chacun doté de trois boutons. Chaque groupe de radio peut ensuite être aligné avec un gridView, ou relativeLayout, etc.
Au lieu d'utiliser le standard OnCheckedChangeListener de RadioButton, utilisez celui (du même nom) appartenant au CompoundButton.
Ensuite, chaque fois que vous appuyez sur un bouton RadioButton, vous pouvez utiliser les groupes de radio pour désélectionner les boutons radio. Puis sélectionnez par programme le bouton radio sur lequel vous avez cliqué.
C'est une solution horrible, mais elle fonctionne comme on l'espère.
Vous trouverez ci-dessous un exemple de code que j'avais l'habitude de faire avec une disposition de boutons 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);
}