Android: Wie binde ich den Spinner an eine benutzerdefinierte Objektliste?


126

In der Benutzeroberfläche muss sich ein Drehfeld befinden, das einige Namen enthält (die Namen sind sichtbar), und jeder Name hat eine eigene ID (die IDs entsprechen nicht der Anzeigereihenfolge). Wenn der Benutzer den Namen aus der Liste auswählt, muss die Variable currentID geändert werden.

Die Anwendung enthält die ArrayList

Wobei Benutzer ein Objekt mit ID und Name ist:

public class User{
        public int ID;
        public String name;
    }

Was ich nicht weiß, ist, wie man einen Spinner erstellt, der die Liste der Benutzernamen anzeigt und Spinner-Elemente an IDs bindet. Wenn das Spinner-Element ausgewählt / geändert wird, wird die Variable currentID auf den entsprechenden Wert gesetzt.

Ich würde mich freuen, wenn jemand die Lösung des beschriebenen Problems zeigen oder einen Link zur Lösung des Problems bereitstellen könnte.

Vielen Dank!


Verwenden Sie die setVisibility-Methode und setzen Sie sie auf INVISIBLE developer.android.com/reference/android/view/…
andoni90

Antworten:


42

Sie können sich diese Antwort ansehen . Sie können auch einen benutzerdefinierten Adapter verwenden, die folgende Lösung ist jedoch für einfache Fälle in Ordnung.

Hier ist ein Re-Post:

Wenn Sie also hierher gekommen sind, weil Sie sowohl Beschriftungen als auch Werte im Spinner haben möchten, habe ich Folgendes getan:

  1. Erstellen Sie einfach Ihre wie Spinnergewohnt
  2. Definieren Sie 2 gleich große Arrays in Ihrer array.xmlDatei - ein Array für Beschriftungen und ein Array für Werte
  3. Stellen Sie Ihre Spinnermitandroid:entries="@array/labels"
  4. Wenn Sie einen Wert benötigen, gehen Sie wie folgt vor (nein, Sie müssen ihn nicht verketten):

      String selectedVal = getResources().getStringArray(R.array.values)[spinner.getSelectedItemPosition()];

2
Gibt es eine elegante Möglichkeit, auf die definierten Beschriftungen zuzugreifen (zum Vergleich mit selectedVal), um zu vermeiden, dass die Zeichenfolgenbeschriftungen im Code hart codiert werden?
Anti Erde

Dies ist ein Fall von Datenverdoppelung und sollte vermieden werden.
Binoy Babu

18
Aus Sicht der Skalierbarkeit also falsch - es bedeutet, dass Ihre "Objekte" niemals dynamisch sein können - schlechte Praxis
Srneczek

1
@ Boston Ich habe die Zeit nicht überprüft, aber ich denke, dass es in diesem Fall irrelevant ist. Adapter sind aus irgendeinem Grund vorhanden, und ich wette, es geht nicht um eine zeitliche Änderung des SDK. Dies ist einer der Gründe, warum sie überhaupt Adapter erstellt haben. Sie können also eine Liste komplexer Objekte bereitstellen, daher war dies meiner Meinung nach immer eine schlechte Praxis, die nur in sehr einfachen Fällen verwendet werden kann, aber das macht es nicht zu einer guten Praxis.
Srneczek

3
@ Bob'sBurgers Sie verpassen den Punkt. Ich habe nie gesagt, dass es nicht funktioniert. Ich habe gesagt, dass es eine schlechte Praxis ist und ich habe Recht damit. Globale Variablen oder Code in einer sehr, sehr langen Datei funktionieren auch, wissen Sie ... Übrigens sollten Sie alte Threads kommentieren, da sie in der heutigen Suche immer noch vorkommen und ppl diese (heutigen) falschen Antworten verwendet.
Srneczek

344

Ich weiß, dass der Thread alt ist, aber nur für den Fall ...

Benutzerobjekt:

public class User{

    private int _id;
    private String _name;

    public User(){
        this._id = 0;
        this._name = "";
    }

    public void setId(int id){
        this._id = id;
    }

    public int getId(){
        return this._id;
    }

    public void setName(String name){
        this._name = name;
    }

    public String getName(){
        return this._name;
    }
}

Benutzerdefinierter Spinner-Adapter (ArrayAdapter)

public class SpinAdapter extends ArrayAdapter<User>{

    // Your sent context
    private Context context;
    // Your custom values for the spinner (User)
    private User[] values;

    public SpinAdapter(Context context, int textViewResourceId,
            User[] values) {
        super(context, textViewResourceId, values);
        this.context = context;
        this.values = values;
    }

    @Override
    public int getCount(){
       return values.length;
    }

    @Override
    public User getItem(int position){
       return values[position];
    }

    @Override
    public long getItemId(int position){
       return position;
    }


    // And the "magic" goes here
    // This is for the "passive" state of the spinner
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // I created a dynamic TextView here, but you can reference your own  custom layout for each spinner item
        TextView label = (TextView) super.getView(position, convertView, parent);
        label.setTextColor(Color.BLACK);
        // Then you can get the current item using the values array (Users array) and the current position
        // You can NOW reference each method you has created in your bean object (User class)
        label.setText(values[position].getName());

        // And finally return your dynamic (or custom) view for each spinner item
        return label;
    }

    // And here is when the "chooser" is popped up
    // Normally is the same view, but you can customize it if you want
    @Override
    public View getDropDownView(int position, View convertView,
            ViewGroup parent) {
        TextView label = (TextView) super.getDropDownView(position, convertView, parent);
        label.setTextColor(Color.BLACK);
        label.setText(values[position].getName());

        return label;
    }
}

Und die Umsetzung:

public class Main extends Activity {
    // You spinner view
    private Spinner mySpinner;
    // Custom Spinner adapter (ArrayAdapter<User>)
    // You can define as a private to use it in the all class
    // This is the object that is going to do the "magic"
    private SpinAdapter adapter;

        @Override
        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create the Users array
        // You can get this retrieving from an external source
        User[] users = new User[2];

        users[0] = new User();
        users[0].setId(1);
        users[0].setName("Joaquin");

        users[1] = new User();
        users[1].setId(2);
        users[1].setName("Alberto");

        // Initialize the adapter sending the current context
        // Send the simple_spinner_item layout
        // And finally send the Users array (Your data)
        adapter = new SpinAdapter(Main.this,
            android.R.layout.simple_spinner_item,
            users);
        mySpinner = (Spinner) findViewById(R.id.miSpinner);
        mySpinner.setAdapter(adapter); // Set the custom adapter to the spinner
        // You can create an anonymous listener to handle the event when is selected an spinner item
        mySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view,
                    int position, long id) {
                // Here you get the current item (a User object) that is selected by its position
                User user = adapter.getItem(position);
                // Here you can do the action you want to...
                Toast.makeText(Main.this, "ID: " + user.getId() + "\nName: " + user.getName(),
                    Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onNothingSelected(AdapterView<?> adapter) {  }
        });
    }
}

43
Dies sollte die akzeptierte Antwort sein. Das Erstellen eines benutzerdefinierten Adapters ist definitiv der richtige Weg.
Jamesc

11
Das hat gut funktioniert. Sehr schön. Aber ein Problem. Der Spinner änderte nun seinen Stil. Ich versuche, eine neue XML-Datei festzulegen, um die Auffüllungen und die Textgröße zu ändern, aber es passiert nichts. Ich ändere den Spinner selbst von der XML und noch nichts. Das einzige, was sich ändert, ist, wenn ich die Textgröße der Textansicht aus dem SpinAdapter heraus ändere. Gibt es eine Möglichkeit, den Standard-Spinner-Stil / -Thema beizubehalten, aber diese Art von Werten zu laden?
Lantonis

Ich habe das getan, aber ich bekomme eine enorme Verzögerung. Während ich nur 3 mal hinzufüge. Ich habe eine Ansicht aufgeblasen, um mein Layout zu erstellen. Sie enthält nur ein Symbol und Text. Der Logcat bestätigt mich mit den Worten Skipped 317 frames! The application may be doing too much work on its main thread.Irgendwelche Ideen?
CularBytes

3
+1 für diese Zeile :) Benutzer user = adapter.getItem (Position);
Ahmad Alkhatib

2
Nur eine Änderung, um die Ansicht wiederzuverwenden, anstatt eine neue TextView zu erstellen, sollte dies folgendermaßen aussehen: TextView label = (TextView) super.getView (position, convertView, parent)
jackcar

93

Einfachste Lösung

Nachdem ich verschiedene Lösungen in SO durchsucht hatte, stellte ich fest, dass die folgende Lösung die einfachste und sauberste ist, um eine Spinnermit benutzerdefinierten zu füllen Objects. Hier ist die vollständige Implementierung:

User.java

public class User{
    public int ID;
    public String name;

    @Override
    public String toString() {
        return this.name; // What to display in the Spinner list.
    }
}    

res / layout / spinner.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="14sp"
    android:textColor="#FFFFFF"
    android:spinnerMode="dialog" />

res / layout / your_activity_view.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="fill_parent"
    android:orientation="vertical">

    <Spinner android:id="@+id/user" />

</LinearLayout>

In Ihrer Aktivität

List<User> users = User.all(); // This example assumes you're getting all Users but adjust it for your Class and needs.
ArrayAdapter userAdapter = new ArrayAdapter(this, R.layout.spinner, users);

Spinner userSpinner = (Spinner) findViewById(R.id.user);
userSpinner.setAdapter(userAdapter);
userSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        // Get the value selected by the user
        // e.g. to store it as a field or immediately call a method
        User user = (User) parent.getSelectedItem();
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }
});

Eine kleine Einschränkung ist, dass dies nicht eingestellt wird, currentIDsobald sich der Spinner- Wert ändert. Meistens benötigen Sie den Wert des Spinners erst, nachdem Sie anschließend auf eine Schaltfläche wie Senden oder Speichern geklickt haben , nicht unmittelbar nachdem sich der Spinner geändert hat. Wenn dies vermieden werden kann, bietet dies eine viel einfachere Lösung.
Joshua Pinter

Ich fand, dass dies funktioniert, und indem Sie einfach die letzte Zeile an eine andere Stelle setzen, können Sie das beschriebene "Problem" @JoshPinter umgehen.
x13

@ x13 Das stimmt. Alles, was Sie tun müssen, um den Wert für die Änderung zu erhalten, ist, einen Listener für die Änderung einzurichten und dann den getSelectedItem()Anruf darin zu tätigen. Danke für den Tipp.
Joshua Pinter

4
3 Jahre sind vergangen und funktionieren fantastisch! Ich kann nicht glauben, dass die Leute diese einfache Sache überkomplizieren.
Juan De la Cruz

1
@JuanDelaCruz Android und Java machen es einfach, Dinge zu komplizieren. Vereinfachung für den Sieg!
Joshua Pinter

53

Für einfache Lösungen können Sie einfach den "toString" in Ihrem Objekt überschreiben

public class User{
    public int ID;
    public String name;

    @Override
    public String toString() {
        return name;
    }
}

und dann können Sie verwenden:

ArrayAdapter<User> dataAdapter = new ArrayAdapter<User>(mContext, android.R.layout.simple_spinner_item, listOfUsers);

Auf diese Weise zeigt Ihr Spinner nur die Benutzernamen an.


Wie setze ich den Drehknopf auf BEARBEITEN auf das ausgewählte Element, das bei Antwort zurückkehrt?
Arnold Brown

9

Mit Abstand der einfachste Weg, den ich gefunden habe:

@Override
public String toString() {
    return this.label;           
}

Jetzt können Sie jedes Objekt in Ihren Spinner stecken und es wird das angegebene Etikett angezeigt.


8

Nur eine kleine Änderung an Joaquin Albertos Antwort kann das Stilproblem lösen. Ersetzen Sie einfach die Funktion getDropDownView im benutzerdefinierten Adapter wie folgt.

@Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        View v = super.getDropDownView(position, convertView, parent);
        TextView tv = ((TextView) v);
        tv.setText(values[position].getName());
        tv.setTextColor(Color.BLACK);
        return v;
    }

1
Diese Antwort beantwortet die Frage nicht wirklich, aber sie weist darauf hin, dass einige wichtige Dinge mit dieser Antwort zusammenhängen
Sruit A.Suk

6

Funktioniert gut für mich, der Code, der für das getResource () -Ding benötigt wird, lautet wie folgt:

spinner = (Spinner) findViewById(R.id.spinner);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> spinner, View v,
                int arg2, long arg3) {
            String selectedVal = getResources().getStringArray(R.array.compass_rate_values)[spinner.getSelectedItemPosition()];
            //Do something with the value
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
            // TODO Auto-generated method stub
        }

    });

Sie müssen nur (selbst) sicherstellen, dass die Werte in den beiden Arrays richtig ausgerichtet sind!


5

inspiriert von Joaquin Alberto, hat das für mich funktioniert:

public class SpinAdapter extends ArrayAdapter<User>{


    public SpinAdapter(Context context, int textViewResourceId,
            User[] values) {
        super(context, textViewResourceId, values);
    }



    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView label = (TextView) super.getView(position, convertView, parent);
        label.setTextColor(Color.BLACK);
        label.setText(this.getItem(position).getName());
        return label;
    }

    @Override
    public View getDropDownView(int position, View convertView,ViewGroup parent) {
        TextView label = (TextView) super.getView(position, convertView, parent);
        label.setTextColor(Color.BLACK);
        label.setText(this.getItem(position).getName());
        return label;
    }
}

5

Basierend auf dem Beispiel von Joaquin Alberto (danke), funktioniert es jedoch für jeden Typ (Sie sollten toString () im Typ implementieren, damit Sie die Ausgabe formatieren können.

import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class SpinAdapter<T> extends ArrayAdapter<T> {
private Context context;
private List<T> values;

public SpinAdapter(Context context, int textViewResourceId, List<T> values) {
    super(context, textViewResourceId, values);
    this.context = context;
    this.values = values;
}

public int getCount() {
    return values.size();
}

public T getItem(int position) {
    return values.get(position);
}

public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    TextView label = new TextView(context);
    label.setTextColor(Color.BLACK);
    label.setText(values.toArray(new Object[values.size()])[position]
            .toString());
    return label;
}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    TextView label = new TextView(context);
    label.setTextColor(Color.BLACK);
    label.setText(values.toArray(new Object[values.size()])[position]
            .toString());

    return label;
}
}

Ich denke auch, dass Sie List durch Array ersetzen können, damit Sie Array in List nicht ausführen müssen, aber ich hatte eine Liste ..... :)


3

Um den Trick zu verstehen, muss man wissen, wie Adapter im Allgemeinen und ArrayAdapter im Besonderen funktionieren.

Adapter: Sind Objekte, die Datenstrukturen an Widgets binden können. Diese Widgets zeigen diese Daten in einer Liste oder in einem Spinner an.

Die beiden Fragen, die ein Adapter beantwortet, sind:

  1. Welches Widget oder welche zusammengesetzte Ansicht muss einer Datenstruktur (dem Objekt Ihrer Klasse) für einen bestimmten Index zugeordnet werden?
  2. Wie extrahiere ich die Daten aus der Datenstruktur (dem Objekt Ihrer Klasse) und wie setze ich Felder, dh EditTextdes Widgets oder der zusammengesetzten Ansicht, gemäß diesen Daten?

Die Antworten von ArrayAdapter lauten:

  • Jedes Widget (dh row.xmlODERandroid.R.layout.simple_spinner_item ) für einen Index ist dasselbe und wird von der Ressource aufgeblasen, deren ID dem Konstruktor von ArrayAdapter zugewiesen wurde.
  • Es wird erwartet, dass jedes Widget eine Instanz von TextView (oder ein Nachkomme) ist. Die .setText()Methode des Widgets wird mit dem Zeichenfolgenformat des Elements in der unterstützenden Datenstruktur verwendet. Das Zeichenfolgenformat wird durch Aufrufen .toString()des Elements ermittelt.

CustomListViewDemo.java

public class CustomListViewDemo extends ListActivity {
  private EfficientAdapter adap;

  private static String[] data = new String[] { "0", "1", "2", "3", "4" };

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);
    adap = new EfficientAdapter(this);
    setListAdapter(adap);
  }

  @Override
  protected void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    super.onListItemClick(l, v, position, id);
    Toast.makeText(this, "Click-" + String.valueOf(position), Toast.LENGTH_SHORT).show();
  }

  public static class EfficientAdapter extends BaseAdapter implements Filterable {
    private LayoutInflater mInflater;
    private Bitmap mIcon1;
    private Context context;
    int firstpos=0;

    public EfficientAdapter(Context context) {
      // Cache the LayoutInflate to avoid asking for a new one each time.
      mInflater = LayoutInflater.from(context);
      this.context = context;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {

      ViewHolder holder;

      if (convertView == null) {
        convertView = mInflater.inflate(R.layout.adaptor_content, null);

        holder = new ViewHolder();
        holder.sp = (Spinner) convertView.findViewById(R.id.spinner1);

        holder.ArrayAdapter_sp = new ArrayAdapter(parent.getContext(),android.R.layout.simple_spinner_item,data);
        holder.ArrayAdapter_sp.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        holder.sp.setAdapter( holder.ArrayAdapter_sp);
        holder.sp.setOnItemSelectedListener(new OnItemSelectedListener()
        {
            private int pos = position;
            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int p, long arg3) 
            {
                // TODO Auto-generated method stub
                 Toast.makeText(context, "select spinner " + String.valueOf(pos)+" with value ID "+p, Toast.LENGTH_SHORT).show();    

            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0)
            {
                // TODO Auto-generated method stub

            }
        });




        convertView.setTag(holder);
      } else {

        holder = (ViewHolder) convertView.getTag();
      }


      return convertView;
    }

    static class ViewHolder 
    {

        Spinner sp;
        ArrayAdapter ArrayAdapter_sp;

    }

    @Override
    public Filter getFilter() {
      // TODO Auto-generated method stub
      return null;
    }

    @Override
    public long getItemId(int position) {
      // TODO Auto-generated method stub
      return 0;
    }

    @Override
    public int getCount() {
      // TODO Auto-generated method stub
      return data.length;
    }

    @Override
    public Object getItem(int position) {
      // TODO Auto-generated method stub
      return data[position];
    }

  }

}

adaptor_content.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/lineItem"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical" >

    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="314dp"
        android:layout_height="wrap_content" />

</LinearLayout>

main.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent" android:layout_width="fill_parent"
    >

    <ListView
        android:id="@+id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginBottom="60dip"
        android:layout_marginTop="10dip"
        android:cacheColorHint="#00000000"
        android:drawSelectorOnTop="false" />

</RelativeLayout>

Es funktioniert richtig, ich hoffe es ist nützlich.


2

Mein benutzerdefiniertes Objekt ist

/**
 * Created by abhinav-rathore on 08-05-2015.
 */
public class CategoryTypeResponse {
    private String message;

    private int status;

    private Object[] object;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public Object[] getObject() {
        return object;
    }

    public void setObject(Object[] object) {
        this.object = object;
    }

    @Override
    public String toString() {
        return "ClassPojo [message = " + message + ", status = " + status + ", object = " + object + "]";
    }

    public static class Object {
        private String name;
        private String _id;
        private String title;
        private String desc;
        private String xhdpi;
        private String hdpi;
        private String mdpi;
        private String hint;
        private String type;
        private Brands[] brands;


        public String getId() {
            return _id;
        }

        public void setId(String id) {
            this._id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getXhdpi() {
            return xhdpi;
        }

        public void setXhdpi(String xhdpi) {
            this.xhdpi = xhdpi;
        }

        public String getHdpi() {
            return hdpi;
        }

        public void setHdpi(String hdpi) {
            this.hdpi = hdpi;
        }

        public String getMdpi() {
            return mdpi;
        }

        public void setMdpi(String mdpi) {
            this.mdpi = mdpi;
        }

        public String get_id() {
            return _id;
        }

        public void set_id(String _id) {
            this._id = _id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }

        public String getHint() {
            return hint;
        }

        public void setHint(String hint) {
            this.hint = hint;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public Brands[] getBrands() {
            return brands;
        }

        public void setBrands(Brands[] brands) {
            this.brands = brands;
        }

        @Override
        public String toString() {
            return "ClassPojo [name = " + name + "]";
        }
    }

    public static class Brands {

        private String _id;
        private String name;
        private String value;
        private String categoryid_ref;

        public String get_id() {
            return _id;
        }

        public void set_id(String _id) {
            this._id = _id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public String getCategoryid_ref() {
            return categoryid_ref;
        }

        public void setCategoryid_ref(String categoryid_ref) {
            this.categoryid_ref = categoryid_ref;
        }

        @Override
        public String toString() {
            return  name;

        }
    }
}

Ich wollte dieses Objekt auch als Adapterquelle für meinen Spinner festlegen , ohne ArrayAdapter so zu erweitern, dass ich es tat.

brandArray = mCategoryTypeResponse.getObject()[fragPosition].getBrands();

ArrayAdapter brandAdapter = new ArrayAdapter< CategoryTypeResponse.Brands>(getActivity(),
                R.layout.item_spinner, brandArray);

Jetzt können Sie die Ergebnisse in Ihrem Spinner sehen. Der Trick bestand darin, toString() das benutzerdefinierte Objekt zu überschreiben. Welchen Wert Sie auch immer im Spinner anzeigen möchten, geben Sie diesen in dieser Methode zurück.


0

Ich denke, dass die beste Lösung die "einfachste Lösung" von Josh Pinter ist .

Das hat bei mir funktioniert:

//Code of the activity 
//get linearLayout
LinearLayout linearLayout = (LinearLayout ) view.findViewById(R.id.linearLayoutFragment);       

LinearLayout linearLayout = new LinearLayout(getActivity());
//display css
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

//create the spinner in a fragment activiy
Spinner spn = new Spinner(getActivity());

// create the adapter.
ArrayAdapter<ValorLista> spinner_adapter = new ArrayAdapter<ValorLista>(getActivity(), android.R.layout.simple_spinner_item, meta.getValorlistaList());
spinner_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
spn.setAdapter(spinner_adapter);

//set the default according to value
//spn.setSelection(spinnerPosition);

linearLayout.addView(spn, params2);
//Code of the class ValorLista

import java.io.Serializable;
import java.util.List;

public class ValorLista implements Serializable{


    /**
     * 
     */
    private static final long serialVersionUID = 4930195743192929192L;
    private int id; 
    private String valor;
    private List<Metadato> metadatoList;


    public ValorLista() {
        super();
        // TODO Auto-generated constructor stub
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getValor() {
        return valor;
    }
    public void setValor(String valor) {
        this.valor = valor;
    }
    public List<Metadato> getMetadatoList() {
        return metadatoList;
    }
    public void setMetadatoList(List<Metadato> metadatoList) {
        this.metadatoList = metadatoList;
    }

    @Override
    public String toString() {  
        return getValor();
    }

}

0

Wenn Sie keine separate Klasse benötigen, meine ich nur einen einfachen Adapter, der Ihrem Objekt zugeordnet ist. Hier ist mein Code, der auf den bereitgestellten ArrayAdapter-Funktionen basiert.

Und weil Sie möglicherweise nach der Adaptererstellung ein Element hinzufügen müssen (z. B. asynchrones Laden von Datenbankelementen).

Einfach aber effizient.

editCategorySpinner = view.findViewById(R.id.discovery_edit_category_spinner);

// Drop down layout style - list view with radio button         
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

// attaching data adapter to spinner, as you can see i have no data at this moment
editCategorySpinner.setAdapter(dataAdapter);
final ArrayAdapter<Category> dataAdapter = new ArrayAdapter<Category>

(getActivity(), android.R.layout.simple_spinner_item, new ArrayList<Category>(0)) {


        // And the "magic" goes here
        // This is for the "passive" state of the spinner
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // I created a dynamic TextView here, but you can reference your own  custom layout for each spinner item
            TextView label = (TextView) super.getView(position, convertView, parent);
            label.setTextColor(Color.BLACK);
            // Then you can get the current item using the values array (Users array) and the current position
            // You can NOW reference each method you has created in your bean object (User class)
            Category item = getItem(position);
            label.setText(item.getName());

            // And finally return your dynamic (or custom) view for each spinner item
            return label;
        }

        // And here is when the "chooser" is popped up
        // Normally is the same view, but you can customize it if you want
        @Override
        public View getDropDownView(int position, View convertView,
                                    ViewGroup parent) {
            TextView label = (TextView) super.getDropDownView(position, convertView, parent);
            label.setTextColor(Color.BLACK);
            Category item = getItem(position);
            label.setText(item.getName());

            return label;
        }
    };

Und dann können Sie diesen Code verwenden (ich konnte Category [] nicht in den Adapterkonstruktor einfügen, da die Daten separat geladen werden).

Beachten Sie, dass adapter.addAll (items) den Spinner aktualisiert, indem Sie notifyDataSetChanged () in internal aufrufen.

categoryRepository.getAll().observe(this, new Observer<List<Category>>() {

            @Override
            public void onChanged(@Nullable final List<Category> items) {
                dataAdapter.addAll(items);
            }
});

-1

Machen:

spinner.adapter = object: ArrayAdapter<Project>(
            container.context,
            android.R.layout.simple_spinner_dropdown_item,
            state.projects
        ) {
            override fun getDropDownView(
                position: Int,
                convertView: View?,
                parent: ViewGroup
            ): View {
                val label = super.getView(position, convertView, parent) as TextView
                label.text = getItem(position)?.title
                return label
            }

            override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
                val label = super.getView(position, convertView, parent) as TextView
                label.text = getItem(position)?.title
                return label
            }
        }

3
Sie erweitern hier noch eine Klasse. Du machst es nur mit einem anonymen Objekt.
FutureShocked
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.