Java 如何按值而不是按位置设置 Spinner 的选定项目?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2390102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set selected item of Spinner by value, not by position?
提问by Pentium10
I have a update view, where I need to preselect the value stored in database for a Spinner.
我有一个更新视图,我需要在其中为 Spinner 预先选择存储在数据库中的值。
I was having in mind something like this, but the Adapter
has no indexOf
method, so I am stuck.
我正在考虑这样的事情,但Adapter
没有indexOf
方法,所以我被卡住了。
void setSpinner(String value)
{
int pos = getSpinnerField().getAdapter().indexOf(value);
getSpinnerField().setSelection(pos);
}
采纳答案by Merrill
Suppose your Spinner
is named mSpinner
, and it contains as one of its choices: "some value".
假设您Spinner
的名称为mSpinner
,并且它包含作为其选择之一:“某个值”。
To find and compare the position of "some value" in the Spinner use this:
要查找和比较 Spinner 中“某个值”的位置,请使用以下命令:
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 != null) {
int spinnerPosition = adapter.getPosition(compareValue);
mSpinner.setSelection(spinnerPosition);
}
回答by Mark B
I keep a separate ArrayList of all the items in my Spinners. This way I can do indexOf on the ArrayList and then use that value to set the selection in the Spinner.
我在我的微调器中保留了一个单独的 ArrayList 的所有项目。通过这种方式,我可以在 ArrayList 上执行 indexOf,然后使用该值在 Spinner 中设置选择。
回答by JPM
There is actually a way to get this using an index search on the AdapterArray and all this can be done with reflection. I even went one step further as I had 10 Spinners and wanted to set them dynamically from my database and the database holds the value only not the text as the Spinner actually changes week to week so the value is my id number from the database.
实际上有一种方法可以使用 AdapterArray 上的索引搜索来获得它,并且所有这些都可以通过反射来完成。我什至更进一步,因为我有 10 个微调器,并想从我的数据库中动态设置它们,数据库只保存值而不是文本,因为微调器实际上每周都在变化,所以值是我从数据库中获取的 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);
}
Here is the indexed search you can use on almost any list as long as the fields are on top level of object.
这是您几乎可以在任何列表上使用的索引搜索,只要这些字段位于对象的顶层即可。
/**
* 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<Device> needs to be passed as a List<Object> or Object[ ] by using
* Arrays.asList(device.toArray( )).
*
* @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
}
Cast method which can be create for all primitives here is one for string and int.
这里可以为所有基元创建的 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;
}
回答by Scott.N
here is my solution
这是我的解决方案
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()));
and getItemIndexById below
和 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;
}
Hope this help!
希望这有帮助!
回答by max4ever
Based on Merrill's answer here is how to do with a CursorAdapter
基于 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;
}
}
回答by ArtOfWarfare
Based on Merrill's answer, I came up with this single line solution... it's not very pretty, but you can blame whoever maintains the code for Spinner
for neglecting to include a function that does this for that.
基于Merrill 的回答,我想出了这个单行解决方案......它不是很漂亮,但是你可以责怪维护代码Spinner
的人忽略了包含一个为此执行此操作的函数。
mySpinner.setSelection(((ArrayAdapter<String>)mySpinner.getAdapter()).getPosition(myString));
You'll get a warning about how the cast to a ArrayAdapter<String>
is unchecked... really, you could just use an ArrayAdapter
as Merrill did, but that just exchanges one warning for another.
您将收到有关如何ArrayAdapter<String>
取消选中a 的警告……实际上,您可以ArrayAdapter
像 Merrill 那样使用 an ,但这只是将一个警告换成了另一个警告。
回答by xbakesx
If you need to have an indexOf method on any old Adapter (and you don't know the underlying implementation) then you can use this:
如果您需要在任何旧适配器上使用 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;
}
回答by Jaz
I had the same issue when trying to select the correct item in a spinner populated using a cursorLoader. I retrieved the id of the item I wanted to select first from table 1 and then used a CursorLoader to populate the spinner. In the onLoadFinished I cycled through the cursor populating the spinner's adapter until I found the item that matched the id I already had. Then assigned the row number of the cursor to the spinner's selected position. It would be nice to have a similar function to pass in the id of the value you wish to select in the spinner when populating details on a form containing saved spinner results.
尝试在使用 cursorLoader 填充的微调器中选择正确的项目时,我遇到了同样的问题。我首先从表 1 中检索我想选择的项目的 id,然后使用 CursorLoader 填充微调器。在 onLoadFinished 中,我通过光标循环填充微调器的适配器,直到找到与我已有的 id 匹配的项目。然后将光标的行号分配给微调器的选定位置。当在包含保存的微调器结果的表单上填充详细信息时,最好有一个类似的函数来传递您希望在微调器中选择的值的 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
}
回答by Akhil Jain
A simple way to set spinner based on value is
根据值设置微调器的一种简单方法是
mySpinner.setSelection(getIndex(mySpinner, myValue));
//private method of your class
private int getIndex(Spinner spinner, String myString){
for (int i=0;i<spinner.getCount();i++){
if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(myString)){
return i;
}
}
return 0;
}
Way to complex code are already there, this is just much plainer.
复杂代码的方法已经存在,这只是简单得多。
回答by PrvN
You can use this also,
你也可以用这个,
String[] baths = getResources().getStringArray(R.array.array_baths);
mSpnBaths.setSelection(Arrays.asList(baths).indexOf(value_here));