如何在ListView自定义适配器中使用RadioGroup?

我想在我的列表中显示一个select选项。 我在我的listView行中使用RadioButton。 我知道RadioGroup用于单选。

但问题是我已经在我的ListRowView中添加了单选button。 现在我想在一个RadioButton中添加我所有的列表项。 我使用自定义适配器,并在getView()。 我在getView()中获取单选button,但是想要在RadioGroup中添加它时,它会说

“查看allready已经有父母,调用removeView()父母之前”

而且我知道它是真实的,但如果我从视图中删除它。 那么它是不可见的。

我也尝试以编程方式创build和添加RadioButton。 然后将它添加到RadioGrop中。 然后查看列表行。 但这一次,作为RadioGroup的父母,它再次说

“查看allready已经有父母,调用removeView()父母之前”

我想要做的是一次只select列表中的一个项目。 我的代码如下。

getView

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

我的XML的行

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

它看起来像这样,如果我不使用RadioGroup

你需要做两件事情:

  1. 使用mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
  2. 使您的自定义行视图实现可检查。 (更多信息在这里 )。

这个解决scheme的工作原理,它很干净,但可能有一些更好的解决scheme。

你应该使用你的适配器来pipe理单选button的状态。

您必须保持对最后一次选中的单选button的引用,然后在RadioButton.onClick设置最后选中的单选buttonsetChecked(false)

还记得将新select的单选button设置为最后select的单选button。

看例子:

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

希望它为你做。

这是我的解决scheme。 它很容易。

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

你可以把一个

 private int selectedIndex = -1; 

然后,在getView代码中,你可以检查

 if (position == selectedIndex) { rbtn.setSelected ( true ); } else { rbtn.setSelected ( false ); } 

并在您的自定义适配器中添加一个方法:

 public void setSelectedIndex(int index) { //some range-checks, maybe selectedIndex = index; //invalidate } 

然后,在你的onItemClickedListener你调用setSelectedIndex的位置。

您需要使用CheckedTextView而不是普通的。 http://developer.android.com/reference/android/widget/CheckedTextView.html

我从来没有使用它,但AlertDialog将它用于SingleChoice项目。 所以它肯定会工作:)

编辑:不要忘记打电话

  listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 

添加到已经给出的答案,为了更模块化的方法,所有列表项都从具有消息function的相同类/接口inheritance,这将允许您通过适配器传递消息。
适配器向每个添加到它的项目注册自己,因此每个列表项都可以调用适配器来发送消息。 那么在RadioButton监听器中,你可以发送一个消息给所有其他的单选buttonclosures,打开按下的button,最后通知在适配器上改变的数据集。

我有一个ListAdapter类,和一个相当健壮的ListItem抽象类; 我会发给任何需要它的人。
支持多个列表项目types。

你需要相同的输出或不同的…

我的意思是你只select列表中的一种语言。 这样对吗?

符合它。 所以我会举一个例子