我有一个更新视图,在那里我需要预先选择存储在数据库中的值为一个微调器。
我有这样的想法,但适配器没有indexOf方法,所以我被卡住了。
void setSpinner(String value)
{
int pos = getSpinnerField().getAdapter().indexOf(value);
getSpinnerField().setSelection(pos);
}
我有一个更新视图,在那里我需要预先选择存储在数据库中的值为一个微调器。
我有这样的想法,但适配器没有indexOf方法,所以我被卡住了。
void setSpinner(String value)
{
int pos = getSpinnerField().getAdapter().indexOf(value);
getSpinnerField().setSelection(pos);
}
当前回答
实际上有一种方法可以使用AdapterArray上的索引搜索来获得这个,所有这些都可以通过反射来完成。我甚至更进一步,因为我有10个Spinners,并希望从我的数据库中动态设置它们,数据库只保存值而不是文本,因为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);
}
这里是索引搜索,你可以使用几乎任何列表,只要字段是在对象的顶层。
/**
* 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
}
可以为所有原语创建的强制转换方法是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;
}
其他回答
以下是我的完整解决方案。我有以下enum:
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. httpmethod定义在布局文件中。Simple_spinner_item由android-studio下发。
根据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;
}
}
假设你的Spinner名为mSpinner,它包含一个选项:"some value"。
要查找并比较“some value”在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);
}
根据Merrill的回答,我想出了这个单线解决方案……它不是很漂亮,但是你可以责怪那些维护Spinner代码的人忽略了包含一个这样做的函数。
mySpinner.setSelection(((ArrayAdapter<String>)mySpinner.getAdapter()).getPosition(myString));
你会得到一个警告,关于ArrayAdapter<String>的强制转换是如何未选中的…实际上,您可以像Merrill那样使用ArrayAdapter,但这只是将一个警告交换为另一个警告。
如果警告导致问题,只需添加
@SuppressWarnings("unchecked")
到方法签名或语句之上。
如果你需要在任何旧的适配器上有一个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;
}