Je souhaite afficher une seule option de sélection dans ma liste. J'utilise RadioButton
dans ma rangée listView
. Je sais que RadioGroup
est utilisé pour une sélection unique.
Mais le problème est que j'ai ajouté la RadioButton
dans ma ListRowView
. Maintenant, je veux ajouter tous les éléments de ma liste dans une RadioButton
. J'utilise Custom Adapter
et dans getView()
. Je reçois la RadioButton
dans getView()
, mais quand je veux l’ajouter dans RadioGroup
il est dit
"la vue a déjà un parent, appelez removeView () dans le parent avant"
Et je sais que c'est vrai, mais si je le retire de la vue. Alors ce n'est pas visible.
J'essaie également de créer et d'ajouter RadioButton
par programme. Et puis ajoutez-le dans RadioGrop
. Et puis pour voir la rangée de la liste. Mais cette fois en tant que parent est RadioGroup
, donc encore une fois, il dit
"la vue a déjà un parent, appelez removeView () dans le parent avant"
Ce que je veux faire est de sélectionner un seul élément de la liste à la fois. Mon code est comme suit.
public class MyAdapter extends ArrayAdapter < MyMenuItem > {
private LayoutInflater mInflater ;
int mResource ;
List < MyMenuItem > mData ;
Context context;
public MyAdapter ( Context context , int resource , int textViewResourceId , List < MyMenuItem > data ) {
super ( context , resource , textViewResourceId , data ) ;
this.context = context;
mData = data ;
mResource = resource ;
mInflater = ( LayoutInflater ) getSystemService ( Context.LAYOUT_INFLATER_SERVICE ) ;
}
@ Override
public View getView ( int position , View convertView , ViewGroup parent ) {
ViewHolder holder = null ;
if ( convertView == null ) {
convertView = mInflater.inflate ( mResource , null ) ;
holder = new ViewHolder ( ) ;
holder.icon = ( ImageView ) convertView.findViewById ( R.id.icon ) ;
holder.text = ( TextView ) convertView.findViewById ( R.id.text ) ;
holder.comment = ( TextView ) convertView.findViewById ( R.id.comment ) ;
LinearLayout lin = ( LinearLayout ) convertView.findViewById ( R.id.linerList ) ;
RadioButton rbtn = new RadioButton ( context );
LayoutParams lparam = new LayoutParams ( LayoutParams.WRAP_CONTENT , LayoutParams.WRAP_CONTENT );
rbtn.setSelected ( false );
holder.check = rbtn;
//radioGroup.addView ( rbtn );
lin.addView ( rbtn , 0 );
convertView.setTag ( holder ) ;
} else {
holder = ( ViewHolder ) convertView.getTag ( ) ;
}
holder.text.setText ( mData.get ( position ).getText ( ) ) ;
holder.comment.setText ( mData.get ( position ).getComment ( ) ) ;
holder.icon.setImageResource ( getApplicationContext ( ).getResources ( ).getIdentifier ( mData.get ( position ).getIcon ( ) ,
"drawable" , getPackageName ( ) )
) ;
return convertView ;
}
}
Mon XML pour la ligne
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="?android:attr/listPreferredItemHeight"
Android:padding="6dip">
<LinearLayout
Android:id = "@+id/linerList"
Android:orientation="horizontal"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content">
<ImageView
Android:id="@+id/icon"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginRight="6dip" />
</LinearLayout>
<LinearLayout
Android:orientation="vertical"
Android:layout_width="wrap_content"
Android:layout_weight="1"
Android:layout_height="fill_parent">
<TextView
Android:id="@+id/text"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:gravity="center_vertical"
Android:text="My Application"
Android:textSize="20sp"
Android:singleLine="true"
Android:ellipsize="Marquee"
Android:textColor="@color/white" />
<TextView
Android:id="@+id/comment"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:singleLine="true"
Android:ellipsize="Marquee"
Android:text="Simple application that shows how to use RelativeLayout"
Android:textSize="14sp"
Android:textColor="@color/light_gray" />
</LinearLayout>
Vous devez faire deux choses:
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Checkable
. (Plus d'infos sur ce ici ).Cette solution fonctionne et elle est assez propre, mais il existe peut-être de meilleures solutions.
Vous devez utiliser votre adaptateur pour gérer l'état des boutons radio.
Vous devez conserver une référence au dernier bouton radio coché, puis sur RadioButton.onClick
vous définissez le dernier bouton radio coché setChecked(false)
.
n'oubliez pas également de définir le bouton radio nouvellement sélectionné comme dernier bouton radio sélectionné.
voir exemple:
private class MyAdapter extends ArrayAdapter<String>{
private int mResourceId = 0;
private LayoutInflater mLayoutInflater;
private RadioButton mSelectedRB;
private int mSelectedPosition = -1;
public MyAdapter(Context context, int resource, int textViewResourceId, List<String> objects) {
super(context, resource, textViewResourceId, objects);
mResourceId = resource;
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if(view == null){
view = mLayoutInflater.inflate(mResourceId, parent, false);
holder = new ViewHolder();
holder.name = (TextView)view.findViewById(R.id.text);
holder.radioBtn = (RadioButton)view.findViewById(R.id.radioButton1);
view.setTag(holder);
}else{
holder = (ViewHolder)view.getTag();
}
holder.radioBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(position != mSelectedPosition && mSelectedRB != null){
mSelectedRB.setChecked(false);
}
mSelectedPosition = position;
mSelectedRB = (RadioButton)v;
}
});
if(mSelectedPosition != position){
holder.radioBtn.setChecked(false);
}else{
holder.radioBtn.setChecked(true);
if(mSelectedRB != null && holder.radioBtn != mSelectedRB){
mSelectedRB = holder.radioBtn;
}
}
holder.name.setText(getItem(position));
return view;
}
private class ViewHolder{
TextView name;
RadioButton radioBtn;
}
}
J'espère que ça le fait pour vous.
Ceci est ma solution. C'est assez facile.
my_radio_adapter_item.xml:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<TextView
Android:id="@+id/name"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight="1"
... />
<RadioButton
Android:id="@+id/radio"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:clickable="false"
Android:focusable="false"
... />
</LinearLayout>
MyRadioAdapter.Java
public class MyRadioAdapter extends BaseAdapter
{
private Context mContext;
private ArrayList<Variation> mVariations;
private int mSelectedVariation;
public MyRadioAdapter(Context context, ArrayList<Variation> variations, int selectedVariation)
{
mContext = context;
mVariations = variations;
mSelectedVariation = selectedVariation;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
View view = convertView;
if(view==null)
{
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.my_radio_adapter_item, null);
}
final Variation variation = mVariations.get(position);
TextView name = (TextView) view.findViewById(R.id.name);
RadioButton radio = (RadioButton) view.findViewById(R.id.radio);
name.setText(variation.getName());
if(position==mSelectedVariation) radio.setChecked(true);
else radio.setChecked(false);
view.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
mSelectedVariation = position;
MyRadioAdapter.this.notifyDataSetChanged();
}
});
return view;
}
...
}
Tu pourrais mettre un
private int selectedIndex = -1;
puis, dans le code getView, vous pouvez vérifier
if (position == selectedIndex) {
rbtn.setSelected ( true );
}
else {
rbtn.setSelected ( false );
}
et ajoutez une méthode à votre adaptateur personnalisé:
public void setSelectedIndex(int index) {
//some range-checks, maybe
selectedIndex = index;
//invalidate
}
Ensuite, dans votre onItemClickedListener, vous appelez setSelectedIndex sur la position.
Vous devez utiliser CheckedTextView au lieu de la normale . http://developer.Android.com/reference/Android/widget/CheckedTextView.html
Je ne l'ai jamais utilisé, mais AlertDialog l'utilise pour les éléments SingleChoice. Donc ça va définitivement marcher :)
Edit: N'oubliez pas d'appeler
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
pour ajouter aux réponses déjà données, pour une approche plus modulaire, faites en sorte que tous les éléments de la liste héritent de la même classe/interface et disposent d'une fonction de message vous permettant de leur transmettre des messages via l'adaptateur.
L'adaptateur s'enregistre avec chaque élément ajouté, de sorte que chaque élément de la liste peut appeler l'adaptateur pour envoyer un message . Dans l'écouteur RadioButton, vous pouvez également envoyer un message à tous les autres boutons radio. éteignez, allumez le bouton enfoncé, puis finalement notifiez le jeu de données modifié sur l'adaptateur.
J'ai une classe ListAdapter et une classe abstraite ListItem assez robustes; Je vais envoyer à quiconque en a besoin.
Plusieurs types d’éléments de liste pris en charge.