wake-up-neo.com

Wie verwende ich RadioGroup in einem benutzerdefinierten ListView-Adapter?

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.

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

38
Arslan

Sie müssen zwei Dinge tun:

  1. Verwenden Sie mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
  2. Setzen Sie Ihre benutzerdefinierte Zeilenansicht in Checkable. (Mehr Infos dazu hier ).
46
Macarse

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.

35
Inon Stelman

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

    ...
}
14
petrnohejl

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.

2
AmITheRWord

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);
1
Dominic Bartl

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.

0
Max Izrin