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

Lesezeit: 8 Minuten

In der Benutzeroberfläche muss es einen Spinner geben, der einige Namen enthält (die Namen sind sichtbar) und jeder Name hat seine eigene ID (die IDs sind nicht gleich 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 User 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, sodass bei Auswahl/Änderung des Spinner-Elements die Variable currentID auf den entsprechenden Wert gesetzt wird.

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

Danke!

Android Wie binde ich den Spinner an eine benutzerdefinierte Objektliste
Joaquín Alberto

Ich weiß, der Thread ist alt, 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) {  }
        });
    }
}

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

    – Jamesc

    27. Januar 2013 um 12:50 Uhr

  • Dies funktionierte gut. 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 aus dem XML und stil nichts. Das einzige, was sich ändert, ist, wenn ich die Textgröße der TextView innerhalb des SpinAdapters ändere. Gibt es eine Möglichkeit, den Standard-Spinner-Stil/das Standardthema beizubehalten, aber diese Art von Werten zu laden?

    – Lantonis

    16. April 2014 um 8:51 Uhr

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

    – CularBytes

    20. Mai 2015 um 19:02 Uhr

  • +1 für diese Zeile 🙂 User user = adapter.getItem(position);

    – Ahmad Alkhatib

    30. September 2015 um 10:06 Uhr

  • Nur eine Änderung, um die Ansicht wiederzuverwenden, anstatt eine neue TextView zu erstellen, sollte sie so aussehen: TextView label = (TextView) super.getView(position, convertView, parent)

    – Wagenheber

    5. Mai 2017 um 13:25 Uhr

Android Wie binde ich den Spinner an eine benutzerdefinierte Objektliste
Josua Pinter

Einfachste Lösung

Nachdem ich verschiedene Lösungen auf SO durchforstet hatte, fand ich die folgende als die einfachste und sauberste Lösung zum Bevölkern von a Spinner mit Brauch Objects. Hier ist die vollständige Implementierung:

Benutzer.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 festgelegt wird currentID sobald Spinner Wert ändert. Meistens benötigen Sie nur den Wert der Spinner nach dem anschließenden Drücken einer Taste, wie z einreichen oder Speichernnicht unmittelbar nach dem Spinner Änderungen und wenn es vermieden werden kann, bietet dies eine viel einfachere Lösung.

    – Joshua Pinter

    16. Januar 2014 um 18:06 Uhr

  • Ich habe festgestellt, dass dies funktioniert, und indem Sie einfach die letzte Zeile an einer anderen Stelle einfügen, können Sie das von @JoshPinter beschriebene “Problem” umgehen.

    – x13

    16. September 2016 um 7:08 Uhr

  • @x13 Das ist richtig. Alles, was Sie tun müssen, um den Wert bei Änderung zu erhalten, ist, einen “on change”-Listener einzurichten und dann die getSelectedItem() ruf das an. Danke für den Tipp.

    – Joshua Pinter

    18. Mai 2017 um 20:55 Uhr

  • 3 Jahre sind vergangen und funktioniert erstaunlich! Ich kann nicht glauben, dass die Leute diese einfache Sache zu kompliziert machen.

    – Juan de la Cruz

    17. Dezember 2017 um 4:43 Uhr

  • @JuanDelaCruz Android und Java machen es einfach, Dinge zu verkomplizieren. Vereinfachung für den Sieg!

    – Joshua Pinter

    18. Dezember 2017 um 2:33 Uhr

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 stelle ich den Spinner auf BEARBEITEN auf das ausgewählte Element ein, das bei der Antwort zurückkehrt?

    – Arnold Braun

    1. Juni 2018 um 4:57 Uhr


Android Wie binde ich den Spinner an eine benutzerdefinierte Objektliste
Boston

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

Hier ein Repost:

Wenn Sie also hierher gekommen sind, weil Sie sowohl Labels als auch Werte im Spinner haben möchten, habe ich es so gemacht:

  1. Erstellen Sie einfach Ihre Spinner der übliche Weg
  2. Definieren Sie 2 gleich große Arrays in Ihrer array.xml file — ein Array für Labels, ein Array für Werte
  3. Setze deine Spinner mit android:entries="@array/labels"
  4. Wenn Sie einen Wert benötigen, machen Sie so etwas (nein, Sie müssen ihn nicht verketten):

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

Bei weitem der einfachste Weg, den ich gefunden habe:

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

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

1646254387 858 Android Wie binde ich den Spinner an eine benutzerdefinierte Objektliste
Savad KP

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

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

1646254387 780 Android Wie binde ich den Spinner an eine benutzerdefinierte Objektliste
Sonja

Funktioniert gut für mich, der Code, der für die Sache getResource () 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!

916040cookie-checkAndroid: Wie binde ich den Spinner an eine benutzerdefinierte Objektliste?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy