Android:如何将微调器绑定到自定义对象列表?

在用户界面中必须有一个包含一些名称(名称可见)的微调框,每个名称都有自己的ID(这些ID不等于显示顺序)。 当用户从列表中select名称时,必须更改variablescurrentID。

该应用程序包含ArrayList

用户是具有ID和名称的对象:

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

我不知道的是如何创build一个微调器,显示用户名称列表,并将微调项目绑定到ID,所以当select/更改微调项目时,variablescurrentID被设置为适当的值。

如果有人能够展示所描述的问题的解决scheme或提供任何有用的链接来解决问题,我将不胜感激。

谢谢!

你可以看看这个答案 。 您也可以使用自定义适配器,但下面的解决scheme适用于简单的情况。

这是一个重新发布:

所以,如果你来到这里是因为你想在Spinner中同时拥有标签和值,那么我就是这么做的:

  1. 只要用通常的方式创build你的Spinner
  2. array.xml文件中定义两个相等大小的数组 – 一个标签数组,一个数组数组
  3. android:entries="@array/labels"设置你的Spinner android:entries="@array/labels"
  4. 当你需要一个价值时,做一些这样的事情(不,你不必链接它):

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

我知道线程是旧的,但以防万一…

用户对象:

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

自定义微调适配器(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 = new TextView(context); 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 = new TextView(context); label.setTextColor(Color.BLACK); label.setText(values[position].getName()); return label; } } 

而实施:

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

最简单的解决scheme

在search到不同的解决scheme之后,我发现以下是用自定义Objects填充Spinner的最简单,最干净的解决scheme。 这是完整的实现:

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 /布局/ 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 /布局/ 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> 

在你的活动

 // Gets all users but replace with whatever list of users you want. List<User> 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(); 

对于简单的解决scheme,您可以覆盖对象中的“toString”

 public class User{ public int ID; public String name; @Override public String toString() { return name; } } 

然后你可以使用:

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

这样你的微调将只显示用户名。

对我来说工作得很好,在getResource()方面需要的代码如下所示:

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

只需要确保(由你自己)两个数组中的值正确alignment!

灵感来自华金阿尔贝托,这为我工作:

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

基于Joaquin Alberto(谢谢)示例,但它适用于任何types(您应该在types中实现toString(),以便可以格式化输出。

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

此外,我认为你可以replace列表的数组,所以你不需要在列表中做数组,所以我有一个列表….. 🙂

对Joaquin Alberto的答案只是一个小小的调整可以解决风格问题。只需在自定义适配器中replacegetDropDownView函数如下,

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

迄今为止,我发现的最简单的方法是:

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

现在,您可以将任何对象粘贴在微调框中,并显示指定的标签。

为了理解这个技巧,人们必须知道,Adapters是如何工作的,特别是ArrayAdapter。

适配器:是能够将数据结构绑定到窗口小部件的对象,然后这些窗口小部件将这些数据显示在List或Spinner中。

所以适配器回答的两个问题是:

  1. 哪个小部件或合成视图需要与某个数据结构(您的类的对象)关联一个特定的索引?
  2. 如何从数据结构(你的类的对象)中提取数据,以及如何根据这些数据来设置控件或合成视图的字段(即EditText )?

ArrayAdapter的答案是:

  • 对于任何索引,每个控件(即row.xmlandroid.R.layout.simple_spinner_item )都是相同的,并且从ID被赋予给ArrayAdapter构造函数的资源中膨胀。
  • 每个小部件都应该是TextView(或后代)的一个实例。 小部件的.setText()方法将与支持数据结构中项目的string格式一起使用。 string格式将通过调用项目上的.toString()来获得。

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> 

它工作正常,我希望它是有用的。

我的自定义对象是

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

我也想设置这个对象作为我的适配器来源到我的微调没有扩展ArrayAdapter,所以我所做的是。

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

现在你将能够在你的微调器中看到结果,诀窍是在你自定义对象中重写toString() ,所以你想在微调器中显示什么值只是返回这个方法。

我认为最好的解决scheme是Josh Pinter的“最简单的解决scheme” 。

这对我工作:

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