Android: Comment lier le spinner à la liste d'objets personnalisés?

126

Dans l'interface utilisateur, il doit y avoir un spinner qui contient des noms (les noms sont visibles) et chaque nom a son propre ID (les ID ne sont pas égaux à la séquence d'affichage). Lorsque l'utilisateur sélectionne le nom dans la liste, la variable currentID doit être modifiée.

L'application contient la ArrayList

Où User est un objet avec ID et nom:

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

Ce que je ne sais pas, c'est comment créer un spinner qui affiche la liste des noms d'utilisateurs et lier les éléments de spinner aux ID, de sorte que lorsque l'élément de spinner est sélectionné / modifié, la variable currentID est définie sur la valeur appropriée.

J'apprécierais si quelqu'un pouvait montrer la solution du problème décrit ou fournir tout lien utile pour résoudre le problème.

Merci!

Niko Gamulin
la source
Utilisez la méthode setVisibility et définissez-la sur INVISIBLE developer.android.com/reference/android/view/…
andoni90

Réponses:

42

Vous pouvez regarder cette réponse . Vous pouvez également utiliser un adaptateur personnalisé, mais la solution ci-dessous convient aux cas simples.

Voici une nouvelle publication:

Donc, si vous êtes venu ici parce que vous voulez avoir à la fois des étiquettes et des valeurs dans le Spinner, voici comment je l'ai fait:

  1. Créez simplement votre Spinnerfaçon habituelle
  2. Définissez 2 tableaux de taille égale dans votre array.xmlfichier - un tableau pour les étiquettes, un tableau pour les valeurs
  3. Réglez votre Spinneravecandroid:entries="@array/labels"
  4. Lorsque vous avez besoin d'une valeur, faites quelque chose comme ça (non, vous n'avez pas à l'enchaîner):

      String selectedVal = getResources().getStringArray(R.array.values)[spinner.getSelectedItemPosition()];
Bostone
la source
2
Existe-t-il un moyen élégant d'accéder aux étiquettes définies (pour comparaison avec selectedVal), afin d'éviter de coder en dur les étiquettes de chaîne dans le code?
Anti Earth
Il s'agit d'un cas de duplication des données et doit être évité.
Binoy Babu
18
Tellement faux du point de vue de l'évolutivité - cela signifie que vos "objets" ne peuvent jamais être dynamiques - mauvaise pratique
Srneczek
1
@Bostone Je n'ai pas vérifié l'heure mais je pense que ce n'est pas pertinent dans ce cas. Les adaptateurs sont là pour une raison quelconque et je parie qu'il ne s'agit pas de changement de SDK dans le temps. C'est l'une des raisons pour lesquelles ils ont créé des adaptateurs en premier lieu. Donc, vous pouvez servir une liste d'objets complexes, donc cela a toujours été à mon avis une mauvaise pratique utilisable uniquement dans les cas très simples, mais cela n'en fait pas une bonne pratique.
Srneczek
3
@ Bob'sBurgers vous manquez le point. Je n'ai jamais dit que cela ne fonctionnait pas, j'ai dit que c'était une mauvaise pratique et j'ai raison à ce sujet. les variables globales ou le code dans 1 fichier très, très long fonctionnent aussi vous savez ... Btw vous devriez commenter les anciens fils car ils apparaissent toujours dans les recherches d'aujourd'hui et ppl utilisera ces mauvaises réponses (d'aujourd'hui).
Srneczek
344

Je sais que le fil est vieux, mais juste au cas où ...

Objet utilisateur:

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

Adaptateur Spinner personnalisé (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;
    }
}

Et la mise en œuvre:

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) {  }
        });
    }
}
Joaquin Alberto
la source
43
Cela devrait être la réponse acceptée. La création d'un adaptateur personnalisé est certainement la voie à suivre.
jamesc
11
Cela a bien fonctionné. Très agréable. Mais un problème. Le spinner a maintenant changé de style. J'essaie de définir un nouveau xml pour changer les rembourrages, la taille du texte mais rien ne se passe. Je change le spinner lui-même du xml et toujours rien. La seule chose qui change est si je change la taille du texte du TextView à partir du SpinAdapter. Y a-t-il un wa pour garder le style / thème de spinner par défaut mais charger ce type de valeurs?
lantonis
J'ai fait cela, mais je reçois un décalage énorme. Alors que je viens d'ajouter 3 fois. J'ai gonflé une vue pour faire ma mise en page, elle ne contient qu'une icône et du texte. Le logcat me confirme en disant Skipped 317 frames! The application may be doing too much work on its main thread.Des idées?
CularBytes
3
+1 pour cette ligne :) User user = adapter.getItem (position);
Ahmad Alkhatib
2
Juste une modification pour réutiliser la vue, au lieu de créer un nouveau TextView, cela devrait faire comme ceci: TextView label = (TextView) super.getView (position, convertView, parent)
jackcar
93

Solution la plus simple

Après avoir parcouru différentes solutions sur SO, j'ai trouvé que ce qui suit était la solution la plus simple et la plus propre pour peupler un Spinneravec personnalisé Objects. Voici l'implémentation complète:

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>

Dans votre activité

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) {
    }
});
Joshua Pinter
la source
Une petite mise en garde est que cela ne définit pas le currentIDdès que la valeur du Spinner change. La plupart du temps, vous n'avez besoin de la valeur du Spinner qu'après avoir appuyé sur un bouton, tel que Soumettre ou Enregistrer , pas immédiatement après les modifications du Spinner et si cela peut être évité, cela fournit une solution beaucoup plus simple.
Joshua Pinter
J'ai trouvé que cela fonctionnait, et en mettant simplement la dernière ligne ailleurs, vous pouvez contourner le "problème" décrit par @JoshPinter.
x13
@ x13 C'est exact. Tout ce que vous avez à faire pour obtenir la valeur du changement est de configurer un écouteur "on change", puis d'y placer l' getSelectedItem()appel. Merci pour le conseil.
Joshua Pinter
4
3 ans se sont écoulés et fonctionne à merveille! Je ne peux pas croire que les gens compliquent trop cette chose simple.
Juan De la Cruz
1
@JuanDelaCruz Android et java permettent de compliquer facilement les choses. Simplification pour la victoire!
Joshua Pinter
53

Pour des solutions simples, vous pouvez simplement écraser le "toString" dans votre objet

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

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

et ensuite vous pouvez utiliser:

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

De cette façon, votre spinner affichera uniquement les noms d'utilisateurs.

SpyZip
la source
Comment définir le spinner sur EDIT sur l'élément sélectionné qui revient à la réponse?
Arnold Brown
9

De loin le moyen le plus simple que j'ai trouvé:

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

Vous pouvez maintenant coller n'importe quel objet dans votre spinner, et il affichera l'étiquette spécifiée.

NielW
la source
8

Une petite modification de la réponse de Joaquin Alberto peut résoudre le problème de style.Remplacez simplement la fonction getDropDownView dans l'adaptateur personnalisé comme ci-dessous,

@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;
    }
Tirtharup Bhattacharyya
la source
1
cette réponse ne répond pas réellement à la question, mais elle souligne que certaines choses importantes se rapportent à cette réponse
Sruit A.Suk
6

Fonctionne bien pour moi, le code nécessaire autour de la chose getResource () est le suivant:

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
        }

    });

Il suffit de s'assurer (par vous-même) que les valeurs des deux tableaux sont correctement alignées!

Sonja
la source
5

inspiré par Joaquin Alberto, cela a fonctionné pour moi:

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;
    }
}
Anna Maria
la source
5

Basé sur l'exemple de Joaquin Alberto (merci), mais il fonctionne pour n'importe quel type (vous devez implémenter toString () dans le type, afin de pouvoir formater la sortie.

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

Aussi, je pense que vous pouvez remplacer List par Array afin que vous n'ayez pas besoin de faire toArray in List, mais j'avais une liste ..... :)

Alberto Ricart
la source
3

Pour comprendre l'astuce, il faut savoir comment fonctionnent les adaptateurs en général et ArrayAdapter en particulier.

Adaptateurs: sont des objets capables de lier des structures de données à des widgets, puis ces widgets affichent ces données dans une liste ou dans un Spinner.

Les deux questions auxquelles répond un adaptateur sont donc:

  1. Quel widget ou vue composite doit être associé à une structure de données (l'objet de votre classe) pour un certain index?
  2. Comment extraire les données de la structure de données (votre objet de classe) et comment définir le (s) champ (s) ie EditTextdu widget ou de la vue composite en fonction de ces données?

Les réponses d'ArrayAdapter sont:

  • Chaque widget (c'est-à-dire row.xmlOR android.R.layout.simple_spinner_item) pour n'importe quel index est le même, et est gonflé à partir de la ressource dont l'ID a été donné au constructeur d'ArrayAdapter.
  • Chaque widget doit être une instance de TextView (ou un descendant). La .setText()méthode du widget sera utilisée avec le format de chaîne de l'élément dans la structure de données de support. Le format de chaîne sera obtenu en appelant .toString()sur l'élément.

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>

Cela fonctionne correctement, j'espère que c'est utile.

Parag Ghetiya
la source
2

Mon objet personnalisé est

/**
 * 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;

        }
    }
}

Je voulais également définir cet objet comme source de mon adaptateur pour mon spinner sans étendre ArrayAdapter afin que ce que j'ai fait l'était.

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

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

Maintenant, vous pourrez voir les résultats dans votre spinner, l'astuce était de remplacer toString() dans votre objet personnalisé , donc quelle que soit la valeur que vous souhaitez afficher dans le spinner, retournez simplement cela dans cette méthode.

DeltaCap019
la source
0

Je pense que la meilleure solution est la " solution la plus simple" de Josh Pinter .

Cela a fonctionné pour moi:

//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();
    }

}
lopradi
la source
0

Si vous n'avez pas besoin d'une classe séparée, je veux dire juste un simple adaptateur mappé sur votre objet. Voici mon code basé sur les fonctions ArrayAdapter fournies.

Et parce que vous devrez peut-être ajouter un élément après la création de l'adaptateur (par exemple, chargement asynchrone d'un élément de base de données).

Simple mais efficace.

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

Et puis vous pouvez utiliser ce code (je n'ai pas pu mettre Category [] dans le constructeur de l'adaptateur car les données sont chargées séparément).

Notez que adapter.addAll (items) actualise le spinner en appelant notifyDataSetChanged () en interne.

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

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

Faire:

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
            }
        }
Juliano Moraes
la source
3
Vous étendez toujours un cours ici. Vous le faites simplement avec un objet anonyme.
FutureShocked