Android: comment lier spinner à la liste d’objects personnalisés?

Dans l’interface utilisateur, il doit y avoir un spinner qui contient des noms (les noms sont visibles) et chaque nom a son propre identifiant (les identifiants ne sont pas identiques à 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 object avec l’ID et le nom:

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

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

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

Merci!

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

Voici un re-post:

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

  1. Créez simplement votre Spinner la manière habituelle
  2. Définissez 2 tableaux de taille égale dans votre fichier array.xml – un tableau pour les étiquettes, un tableau pour les valeurs
  3. Réglez votre Spinner avec android:ensortinges="@array/labels"
  4. Lorsque vous avez besoin d’une valeur, faites quelque chose comme ça (non, vous n’avez pas besoin de l’enchaîner):

      Ssortingng selectedVal = getResources().getSsortingngArray(R.array.values)[spinner.getSelectedItemPosition()]; 

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

Objet utilisateur:

 public class User{ private int _id; private Ssortingng _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(Ssortingng name){ this._name = name; } public Ssortingng getName(){ return this._name; } } 

Adaptateur Spinner personnalisé (ArrayAdapter)

 public class SpinAdapter extends ArrayAdapter{ // 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) // 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 resortingeving 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) { } }); } } 

Solution la plus simple

Après avoir parcouru différentes solutions sur SO, j’ai trouvé que la solution suivante était la plus simple et la plus propre pour Spinner un Spinner en Objects personnalisés. Voici l’implémentation complète:

User.java

 public class User{ public int ID; public Ssortingng name; @Override public Ssortingng toSsortingng() { return this.name; // What to display in the Spinner list. } } 

res / layout / spinner.xml

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

res / layout / your_activity_view.xml

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

Dans votre activité

 // Gets all users but replace with whatever list of users you want. List users = User.all(); ArrayAdapter userAdapter = new ArrayAdapter(this, R.layout.spinner, users); Spinner userSpinner = (Spinner) findViewById(R.id.user); userSpinner.setAdapter(userAdapter); // And to get the actual User object that was selected, you can do this. User user = (User) ( (Spinner) findViewById(R.id.user) ).getSelectedItem(); 

Pour des solutions simples, vous pouvez simplement écraser le “toSsortingng” dans votre object

 public class User{ public int ID; public Ssortingng name; @Override public Ssortingng toSsortingng() { return name; } } 

et alors vous pouvez utiliser:

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

De cette façon, votre spinner affichera uniquement les noms d’utilisateur.

Juste un petit ajustement à la réponse de Joaquin Alberto peut résoudre le problème de style.Il suffit de remplacer 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; } 

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) { Ssortingng selectedVal = getResources().getSsortingngArray(R.array.compass_rate_values)[spinner.getSelectedItemPosition()]; //Do something with the value } @Override public void onNothingSelected(AdapterView< ?> arg0) { // TODO Auto-generated method stub } }); 

Juste besoin de vous assurer (par vous-même) que les valeurs dans les deux tableaux sont correctement alignées!

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

 public class SpinAdapter extends ArrayAdapter{ 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; } } 

Basé sur Joaquin Alberto (merci) exemple, mais il fonctionne pour tout type (vous devez implémenter le type toSsortingng (), vous pouvez donc 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 extends ArrayAdapter { private Context context; private List values; public SpinAdapter(Context context, int textViewResourceId, List 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] .toSsortingng()); 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] .toSsortingng()); return label; } } 

Aussi, je pense que vous pouvez remplacer List by Array pour ne pas avoir à faire dansArray dans List, mais j’avais une liste ….. 🙂

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

 @Override public Ssortingng toSsortingng() { return this.label; } 

Maintenant, vous pouvez coller n’importe quel object dans votre spinner et il affichera l’étiquette spécifiée.

Pour comprendre le truc, il faut savoir comment fonctionnent les adaptateurs en général et ArrayAdapter en particulier.

Adaptateurs: sont des objects 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 l’adaptateur répond sont donc les suivantes:

  1. Quel widget ou vue composite doit être associé à une structure de données (object de votre classe) pour un certain index?
  2. Comment extraire les données de la structure de données (object de votre classe) et comment définir un ou plusieurs champs, c.-à-d. EditText du widget ou de la vue composite en fonction de ces données?

Les réponses d’ArrayAdapter sont:

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

CustomListViewDemo.java

 public class CustomListViewDemo extends ListActivity { private EfficientAdapter adap; private static Ssortingng[] data = new Ssortingng[] { "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-" + Ssortingng.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 " + Ssortingng.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"?>    

main.xml

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

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

Mon object personnalisé est

 /** * Created by abhinav-rathore on 08-05-2015. */ public class CategoryTypeResponse { private Ssortingng message; private int status; private Object[] object; public Ssortingng getMessage() { return message; } public void setMessage(Ssortingng 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 Ssortingng toSsortingng() { return "ClassPojo [message = " + message + ", status = " + status + ", object = " + object + "]"; } public static class Object { private Ssortingng name; private Ssortingng _id; private Ssortingng title; private Ssortingng desc; private Ssortingng xhdpi; private Ssortingng hdpi; private Ssortingng mdpi; private Ssortingng hint; private Ssortingng type; private Brands[] brands; public Ssortingng getId() { return _id; } public void setId(Ssortingng id) { this._id = id; } public Ssortingng getName() { return name; } public void setName(Ssortingng name) { this.name = name; } public Ssortingng getXhdpi() { return xhdpi; } public void setXhdpi(Ssortingng xhdpi) { this.xhdpi = xhdpi; } public Ssortingng getHdpi() { return hdpi; } public void setHdpi(Ssortingng hdpi) { this.hdpi = hdpi; } public Ssortingng getMdpi() { return mdpi; } public void setMdpi(Ssortingng mdpi) { this.mdpi = mdpi; } public Ssortingng get_id() { return _id; } public void set_id(Ssortingng _id) { this._id = _id; } public Ssortingng getTitle() { return title; } public void setTitle(Ssortingng title) { this.title = title; } public Ssortingng getDesc() { return desc; } public void setDesc(Ssortingng desc) { this.desc = desc; } public Ssortingng getHint() { return hint; } public void setHint(Ssortingng hint) { this.hint = hint; } public Ssortingng getType() { return type; } public void setType(Ssortingng type) { this.type = type; } public Brands[] getBrands() { return brands; } public void setBrands(Brands[] brands) { this.brands = brands; } @Override public Ssortingng toSsortingng() { return "ClassPojo [name = " + name + "]"; } } public static class Brands { private Ssortingng _id; private Ssortingng name; private Ssortingng value; private Ssortingng categoryid_ref; public Ssortingng get_id() { return _id; } public void set_id(Ssortingng _id) { this._id = _id; } public Ssortingng getName() { return name; } public void setName(Ssortingng name) { this.name = name; } public Ssortingng getValue() { return value; } public void setValue(Ssortingng value) { this.value = value; } public Ssortingng getCategoryid_ref() { return categoryid_ref; } public void setCategoryid_ref(Ssortingng categoryid_ref) { this.categoryid_ref = categoryid_ref; } @Override public Ssortingng toSsortingng() { return name; } } } 

Je voulais aussi définir cet object comme source d’adaptateur sur mon spinner sans étendre ArrayAdapter pour que ce que j’ai fait était.

 brandArray = mCategoryTypeResponse.getObject()[fragPosition].getBrands(); ArrayAdapter brandAdapter = new ArrayAdapter< CategoryTypeResponse.Brands>(getActivity(), R.layout.item_spinner, brandArray); 

Maintenant, vous serez en mesure de voir les résultats dans votre spinner, l’astuce consistait à remplacer toSsortingng() dans votre object personnalisé , donc quelle que soit la valeur que vous voulez afficher dans spinner ne fait que le renvoyer dans cette méthode.

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 spinner_adapter = new ArrayAdapter(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 Ssortingng valor; private List metadatoList; public ValorLista() { super(); // TODO Auto-generated constructor stub } public int getId() { return id; } public void setId(int id) { this.id = id; } public Ssortingng getValor() { return valor; } public void setValor(Ssortingng valor) { this.valor = valor; } public List getMetadatoList() { return metadatoList; } public void setMetadatoList(List metadatoList) { this.metadatoList = metadatoList; } @Override public Ssortingng toSsortingng() { return getValor(); } }