45 Stimmen

Wie RadioGroup in ListView benutzerdefinierten Adapter zu verwenden?

Ich möchte eine einzelne Auswahlmöglichkeit in meiner Liste anzeigen. Ich verwende RadioButton in meinem listView Reihe. Ich weiß, dass RadioGroup wird für die Einzelauswahl verwendet.

Das Problem ist jedoch, dass ich die RadioButton in meinem ListRowView . Jetzt möchte ich alle meine Listenelemente in einer einzigen Liste hinzufügen RadioButton . Ich verwende Custom Adapter und in getView() . Ich bekomme die RadioButton en getView() aber wenn Sie es hinzufügen möchten RadioGroup heißt es

"Ansicht hat bereits ein Elternteil, rufen Sie removeView() im Elternteil vorher auf"

Und ich weiß, dass es stimmt, aber wenn ich es aus der Ansicht entferne. Dann ist es nicht sichtbar.

Ich versuche auch, die folgenden Dokumente zu erstellen und hinzuzufügen RadioButton programmatisch. Und dann fügen Sie es in RadioGrop . Und dann zur Ansicht der Listenzeile. Aber dieses Mal ist der übergeordnete RadioGroup , so heißt es wieder

"Ansicht hat bereits ein Elternteil, rufen Sie removeView() im Elternteil vorher auf"

Ich möchte jeweils nur ein Element in der Liste auswählen. Mein Code ist wie folgt.

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

}

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>

It look like this if I not use RadioGroup

46voto

Macarse Punkte 89366

Sie müssen zwei Dinge tun:

  1. Utilice mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
  2. Implementieren Sie Ihre benutzerdefinierte Zeilenansicht Checkable . (Mehr Informationen über dieses aquí ).

38voto

Inon Stelman Punkte 945

Diese Lösung funktioniert und ist ziemlich sauber, aber vielleicht gibt es noch bessere Lösungen.

Sie sollten Ihren Adapter verwenden, um den Zustand der Optionsfelder zu verwalten.

Sie müssen einen Verweis auf das zuletzt markierte Optionsfeld beibehalten, und dann bei RadioButton.onClick Sie setzen das zuletzt markierte Optionsfeld setChecked(false) .

Denken Sie auch daran, das neu ausgewählte Optionsfeld als letztes 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 hilft Ihnen.

15voto

petrnohejl Punkte 7361

Das ist meine Lösung. Es ist ziemlich einfach.

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

    ...
}

2voto

AmITheRWord Punkte 1333

Sie könnten eine

private int selectedIndex = -1;

dann könnte man im getView-Code prüfen

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, in Ihrem onItemClickedListener rufen Sie setSelectedIndex auf die Position.

1voto

Dominic Punkte 3213

Sie müssen die CheckedTextView anstelle der normalen verwenden. http://developer.Android.com/reference/Android/widget/CheckedTextView.html

Ich habe es nie benutzt, aber der AlertDialog verwendet es für die SingleChoice-Elemente. Es wird also auf jeden Fall funktionieren :)

Bearbeiten: anrufen nicht vergessen

 listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X