如何按价值设置选定的Spinner项目,而不是按位置?

我有一个更新视图,我需要预先select一个微调数据库中存储的值。

我想到这样的东西,但Adapter没有indexOf方法,所以我卡住了。

 void setSpinner(String value) { int pos = getSpinnerField().getAdapter().indexOf(value); getSpinnerField().setSelection(pos); } 

假设你的Spinner被命名为mSpinner ,并且它包含一个选项:“some value”。

为了find和比较微调器中的“一些价值”的位置使用这个:

 String compareValue = "some value"; ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.select_state, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mSpinner.setAdapter(adapter); if (!compareValue.equals(null)) { int spinnerPosition = adapter.getPosition(compareValue); mSpinner.setSelection(spinnerPosition); } 

一个简单的方法来设置基于价值微调是

 mySpinner.setSelection(getIndex(mySpinner, myValue)); //private method of your class private int getIndex(Spinner spinner, String myString) { int index = 0; for (int i=0;i<spinner.getCount();i++){ if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(myString)){ index = i; break; } } return index; } 

复杂代码的方式已经在那里,这是更加平常的。

我保留我的Spinners中所有项目的单独ArrayList。 这样我可以对ArrayList做indexOf,然后使用该值在Spinner中设置select。

基于Merrill的回答 ,我提出了这种单线解决scheme…这不是很漂亮,但是你可以责怪谁维护了Spinner的代码,因为忽略了包含一个这样做的函数。

 mySpinner.setSelection(((ArrayAdapter<String>)mySpinner.getAdapter()).getPosition(myString)); 

你会得到一个关于如何对一个ArrayAdapter<String>进行强制转换的警告……实际上,你可以像Merrill那样使用一个ArrayAdapter ,但是这只是为另一个警告交换一个警告。

根据Merrill的答案,这里是如何做一个CursorAdapter

 CursorAdapter myAdapter = (CursorAdapter) spinner_listino.getAdapter(); //cast for(int i = 0; i < myAdapter.getCount(); i++) { if (myAdapter.getItemId(i) == ordine.getListino() ) { this.spinner_listino.setSelection(i); break; } } 

如果你需要在任何旧的适配器上有一个indexOf方法(并且你不知道底层的实现),那么你可以使用这个:

 private int indexOf(final Adapter adapter, Object value) { for (int index = 0, count = adapter.getCount(); index < count; ++index) { if (adapter.getItem(index).equals(value)) { return index; } } return -1; } 

你也可以用这个,

 String[] baths = getResources().getStringArray(R.array.array_baths); mSpnBaths.setSelection(Arrays.asList(baths).indexOf(value_here)); 

如果你正在使用string数组,这是最好的方法:

 int selectionPosition= adapter.getPosition("YOUR_VALUE"); spinner.setSelection(selectionPosition); 

使用以下行select使用值:

 mSpinner.setSelection(yourList.indexOf("value")); 

如果您使用SimpleCursorAdapter (其中columnName是用于填充您的spinner的数据库列的名称),请执行以下操作:

 private int getIndex(Spinner spinner, String columnName, String searchString) { //Log.d(LOG_TAG, "getIndex(" + searchString + ")"); if (searchString == null || spinner.getCount() == 0) { return -1; // Not found } else { Cursor cursor = (Cursor)spinner.getItemAtPosition(0); for (int i = 0; i < spinner.getCount(); i++) { cursor.moveToPosition(i); String itemText = cursor.getString(cursor.getColumnIndex(columnName)); if (itemText.equals(searchString)) { return i; } } return -1; // Not found } } 

(也许你还需要closures游标,这取决于你是否使用一个加载器。)

另外( Akhil的答案的一个改进),这是相应的方式来做到这一点,如果你是从一个数组中填充你的微调:

 private int getIndex(Spinner spinner, String searchString) { if (searchString == null || spinner.getCount() == 0) { return -1; // Not found } else { for (int i = 0; i < spinner.getCount(); i++) { if (spinner.getItemAtPosition(i).toString().equals(searchString)) { return i; // Found! } } return -1; // Not found } }; 

这是我通过string获取索引的简单方法。

 private int getIndexByString(Spinner spinner, String string) { int index = 0; for (int i = 0; i < spinner.getCount(); i++) { if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(string)) { index = i; break; } } return index; } 

实际上有一种方法可以在AdapterArray上使用索引search来获得这一点,所有这些都可以通过reflection来完成。 我甚至更进一步,因为我有10个Spinners,并希望从我的数据库中dynamic设置它们,数据库只保存文本的值,因为Spinner实际上每周都在变化,所以这个值是我的数据库中的id号。

  // Get the JSON object from db that was saved, 10 spinner values already selected by user JSONObject json = new JSONObject(string); JSONArray jsonArray = json.getJSONArray("answer"); // get the current class that Spinner is called in Class<? extends MyActivity> cls = this.getClass(); // loop through all 10 spinners and set the values with reflection for (int j=1; j< 11; j++) { JSONObject obj = jsonArray.getJSONObject(j-1); String movieid = obj.getString("id"); // spinners variable names are s1,s2,s3... Field field = cls.getDeclaredField("s"+ j); // find the actual position of value in the list int datapos = indexedExactSearch(Arrays.asList(Arrays.asList(this.data).toArray()), "value", movieid) ; // find the position in the array adapter int pos = this.adapter.getPosition(this.data[datapos]); // the position in the array adapter ((Spinner)field.get(this)).setSelection(pos); } 

只要这些字段位于对象的顶层,就可以在几乎任何列表中使用索引search。

  /** * Searches for exact match of the specified class field (key) value within the specified list. * This uses a sequential search through each object in the list until a match is found or end * of the list reached. It may be necessary to convert a list of specific objects into generics, * ie: LinkedList&ltDevice&gt needs to be passed as a List&ltObject&gt or Object[&nbsp] by using * Arrays.asList(device.toArray(&nbsp)). * * @param list - list of objects to search through * @param key - the class field containing the value * @param value - the value to search for * @return index of the list object with an exact match (-1 if not found) */ public static <T> int indexedExactSearch(List<Object> list, String key, String value) { int low = 0; int high = list.size()-1; int index = low; String val = ""; while (index <= high) { try { //Field[] c = list.get(index).getClass().getDeclaredFields(); val = cast(list.get(index).getClass().getDeclaredField(key).get(list.get(index)) , "NONE"); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } if (val.equalsIgnoreCase(value)) return index; // key found index = index + 1; } return -(low + 1); // key not found return -1 } 

可以为所有原语创build的Cast方法是一个用于string和int的方法。

  /** * Base String cast, return the value or default * @param object - generic Object * @param defaultValue - default value to give if Object is null * @return - returns type String */ public static String cast(Object object, String defaultValue) { return (object!=null) ? object.toString() : defaultValue; } /** * Base integer cast, return the value or default * @param object - generic Object * @param defaultValue - default value to give if Object is null * @return - returns type integer */ public static int cast(Object object, int defaultValue) { return castImpl(object, defaultValue).intValue(); } /** * Base cast, return either the value or the default * @param object - generic Object * @param defaultValue - default value to give if Object is null * @return - returns type Object */ public static Object castImpl(Object object, Object defaultValue) { return object!=null ? object : defaultValue; } 

这是我的解决scheme

 List<Country> list = CountryBO.GetCountries(0); CountriesAdapter dataAdapter = new CountriesAdapter(this,list); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spnCountries.setAdapter(dataAdapter); spnCountries.setSelection(dataAdapter.getItemIndexById(userProfile.GetCountryId())); 

和getItemIndexById在下面

 public int getItemIndexById(String id) { for (Country item : this.items) { if(item.GetId().toString().equals(id.toString())){ return this.items.indexOf(item); } } return 0; } 

希望这个帮助!

我正在使用自定义适配器,因为这个代码就足够了:

 yourSpinner.setSelection(arrayAdapter.getPosition("Your Desired Text")); 

所以,你的代码片段将是这样的:

 void setSpinner(String value) { yourSpinner.setSelection(arrayAdapter.getPosition(value)); } 

为了让应用程序记住最后select的微调器值,可以使用下面的代码:

  1. 下面的代码读取微调器的值,并相应地设置微调器的位置。

     public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int spinnerPosition; Spinner spinner1 = (Spinner) findViewById(R.id.spinner1); ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource( this, R.array.ccy_array, android.R.layout.simple_spinner_dropdown_item); adapter1.setDropDownViewResource(android.R.layout.simple_list_item_activated_1); // Apply the adapter to the spinner spinner1.setAdapter(adapter1); // changes to remember last spinner position spinnerPosition = 0; String strpos1 = prfs.getString("SPINNER1_VALUE", ""); if (strpos1 != null || !strpos1.equals(null) || !strpos1.equals("")) { strpos1 = prfs.getString("SPINNER1_VALUE", ""); spinnerPosition = adapter1.getPosition(strpos1); spinner1.setSelection(spinnerPosition); spinnerPosition = 0; } 
  2. 并把下面的代码,你知道最新的微调值是存在的,或其他地方的要求。 这段代码基本上将Spinner值写入SharedPreferences中。

      Spinner spinner1 = (Spinner) findViewById(R.id.spinner1); String spinlong1 = spinner1.getSelectedItem().toString(); SharedPreferences prfs = getSharedPreferences("WHATEVER", Context.MODE_PRIVATE); SharedPreferences.Editor editor = prfs.edit(); editor.putString("SPINNER1_VALUE", spinlong1); editor.commit(); 

尝试在使用cursorLoader填充的微调器中select正确的项目时遇到同样的问题。 我从表1中检索到我想要select的项目的id,然后使用CursorLoader来填充微调器。 在onLoadFinished中,我通过填充微调器的适配器的光标循环,直到find与我已有的id相匹配的项目。 然后将光标的行号分配给微调器的选定位置。 如果在包含保存的微调器结果的表单上填充细节时,有一个类似的函数可以传入要在微调器中select的值的id。

 @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { adapter.swapCursor(cursor); cursor.moveToFirst(); int row_count = 0; int spinner_row = 0; while (spinner_row < 0 || row_count < cursor.getCount()){ // loop until end of cursor or the // ID is found int cursorItemID = bCursor.getInt(cursor.getColumnIndexOrThrow(someTable.COLUMN_ID)); if (knownID==cursorItemID){ spinner_row = row_count; //set the spinner row value to the same value as the cursor row } cursor.moveToNext(); row_count++; } } spinner.setSelection(spinner_row ); //set the selected item in the spinner } 

正如前面的一些答案是非常正确的,我只是想从你们没有陷入这样的问题。

如果使用String.format将值设置为ArrayList ,则必须使用相同的string结构String.format获取值的位置。

一个例子:

 ArrayList<String> myList = new ArrayList<>(); myList.add(String.format(Locale.getDefault() ,"%d", 30)); myList.add(String.format(Locale.getDefault(), "%d", 50)); myList.add(String.format(Locale.getDefault(), "%d", 70)); myList.add(String.format(Locale.getDefault(), "%d", 100)); 

你必须得到这样的需要价值的位置:

 myList.setSelection(myAdapter.getPosition(String.format(Locale.getDefault(), "%d", 70))); 

否则,你会得到-1 ,找不到项目!

我使用了Locale.getDefault()因为阿拉伯语

我希望这会对你有所帮助。

这是我希望完整的解决scheme。 我有以下枚举:

 public enum HTTPMethod {GET, HEAD} 

用于以下课程

 public class WebAddressRecord { ... public HTTPMethod AccessMethod = HTTPMethod.HEAD; ... 

通过HTTPMethod enum-member设置微调器的代码:

  Spinner mySpinner = (Spinner) findViewById(R.id.spinnerHttpmethod); ArrayAdapter<HTTPMethod> adapter = new ArrayAdapter<HTTPMethod>(this, android.R.layout.simple_spinner_item, HTTPMethod.values()); mySpinner.setAdapter(adapter); int selectionPosition= adapter.getPosition(webAddressRecord.AccessMethod); mySpinner.setSelection(selectionPosition); 

其中R.id.spinnerHttpmethod在布局文件中定义, android.R.layout.simple_spinner_item由android-studio提供。

您必须传递您的自定义适配器像REPEAT [位置]的位置。 它工作正常。