Ich möchte eine einzelne Auswahloption in meiner Liste anzeigen. Ich verwende RadioButton
in meiner listView
-Zeile. Ich weiß, dass RadioGroup
für die Einzelauswahl verwendet wird.
Das Problem ist jedoch, dass ich die RadioButton
in meine ListRowView
eingefügt habe. Jetzt möchte ich alle meine Listenelemente in einer RadioButton
hinzufügen. Ich verwende Custom Adapter
und in getView()
. Ich bekomme die RadioButton
in getView()
, aber wenn Sie es in RadioGroup
hinzufügen wollen, sagen Sie es
msgstr "Ansicht bereits übergeordnet, rufen Sie removeView () in übergeordnet auf"
Und ich weiß, dass es stimmt, aber wenn ich es aus der Ansicht entferne. Dann ist es nicht sichtbar.
Ich versuche auch, RadioButton
programmgesteuert zu erstellen und hinzuzufügen. Und füge es dann in RadioGrop
hinzu. Und dann zur Anzeige der Listenzeile. Aber diesmal als Elternteil ist RadioGroup
, so heißt es erneut
msgstr "Ansicht bereits übergeordnet, rufen Sie removeView () in übergeordnet auf"
Ich möchte nur jeweils einen Eintrag in der Liste auswählen. Mein Code lautet wie folgt.
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 ;
}
}
Mein XML für die Zeile
<?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>
Sie müssen zwei Dinge tun:
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Checkable
. (Mehr Infos dazu hier ).Diese Lösung funktioniert und ist ziemlich sauber, aber es könnte bessere Lösungen geben.
Sie sollten Ihren Adapter verwenden, um den Status der Optionsschaltflächen zu verwalten.
Sie müssen einen Verweis auf das zuletzt aktivierte Optionsfeld behalten und dann bei RadioButton.onClick
das zuletzt aktivierte Optionsfeld setChecked(false)
einstellen.
denken Sie auch daran, das neu ausgewählte Optionsfeld als zuletzt ausgewähltes Optionsfeld festzulegen.
siehe Beispiel:
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;
}
}
Ich hoffe es tut es für dich.
Das ist meine Lösung. Es ist ziemlich einfach.
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;
}
...
}
Sie könnten einen setzen
private int selectedIndex = -1;
dann kann man im getView-code nachsehen
if (position == selectedIndex) {
rbtn.setSelected ( true );
}
else {
rbtn.setSelected ( false );
}
und fügen Sie eine Methode in Ihrem benutzerdefinierten Adapter hinzu:
public void setSelectedIndex(int index) {
//some range-checks, maybe
selectedIndex = index;
//invalidate
}
Dann rufen Sie in Ihrem onItemClickedListener an der Position setSelectedIndex auf.
Sie müssen die CheckedTextView anstelle der normalen verwenden http://developer.Android.com/reference/Android/widget/CheckedTextView.html
Ich habe es nie verwendet, aber der AlertDialog verwendet es für die SingleChoice-Elemente. So wird es definitiv funktionieren :)
Edit: Vergiss nicht anzurufen
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
um zu den bereits gegebenen Antworten hinzuzufügen, müssen Sie für einen modulareren Ansatz alle Listenelemente von derselben Klasse/Schnittstelle erben, die über eine Nachrichtenfunktion verfügt, mit der Sie Massagen über den Adapter an sie weiterleiten können.
Der Adapter registriert sich bei jedem hinzugefügten Element, sodass jedes Listenelement den Adapter anrufen kann, um eine Nachricht zu senden. Dann können Sie im RadioButton-Listener eine Nachricht an alle anderen Optionsfelder senden ausschalten, den gedrückten einschalten und dann die am Adapter geänderte Datenmenge benachrichtigen.
Ich habe eine ListAdapter-Klasse und eine abstrakte ListItem-Klasse, die ziemlich robust sind. Ich werde an jeden schicken, der es braucht.
Mehrere Listenelementtypen werden unterstützt.