如何设置选定的项目纺锤的价值,而不是由位置?

我有一个更新视图,在那里我需要预先选择存储在数据库中的值为一个微调器。

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

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

我在Spinners中保留了一个单独的数组列表。这样我就可以在数组列表上执行indexOf,然后使用该值在Spinner中设置选择。

假设你的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);
}

实际上有一种方法可以使用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&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
}

可以为所有原语创建的强制转换方法是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;
}

这是我的解决方案

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

希望这对你有所帮助!

基于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代码的人忽略了包含一个这样做的函数。

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

当我试图在使用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


}

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

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

复杂代码的方法已经有了,这只是简单得多。

你也可以用这个,

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

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

  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. And put below code where you know latest spinner values are present, or somewhere else as required. This piece of code basically writes the spinner value in 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();
    

你必须传递你的自定义适配器的位置,如REPEAT[position]。它能正常工作。

如果你使用字符串数组,这是最好的方法:

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

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

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

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

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

下面是如果你正在使用SimpleCursorAdapter(其中columnName是你用来填充spinner的db列的名称)的方法:

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


int initialCursorPos = cursor.getPosition(); //  Remember for later


int index = -1; // Not found
for (int i = 0; i < spinner.getCount(); i++) {


cursor.moveToPosition(i);
String itemText = cursor.getString(cursor.getColumnIndex(columnName));


if (itemText.equals(searchString)) {
index = i; // Found!
break;
}
}


cursor.moveToPosition(initialCursorPos); // Leave cursor as we found it.


return index;
}
}

同样((Akhil的回答的细化),如果你从数组填充你的Spinner,这是相应的方法:

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.format将值设置为ArrayList,则必须使用相同的字符串结构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()是因为阿拉伯语

我希望这对你有帮助。

这是我通过字符串获取索引的简单方法。

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

使用下面的行来选择使用值:

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

以下是我的完整解决方案。我有以下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.simple_spinner_item由android-studio交付。

YourAdapter yourAdapter =
new YourAdapter (getActivity(),
R.layout.list_view_item,arrData);


yourAdapter .setDropDownViewResource(R.layout.list_view_item);
mySpinner.setAdapter(yourAdapter );




String strCompare = "Indonesia";


for (int i = 0; i < arrData.length ; i++){
if(arrData[i].getCode().equalsIgnoreCase(strCompare)){
int spinnerPosition = yourAdapter.getPosition(arrData[i]);
mySpinner.setSelection(spinnerPosition);
}
}

非常简单,只需使用getSelectedItem();

例如:

ArrayAdapter<CharSequence> type=ArrayAdapter.createFromResource(this,R.array.admin_typee,android.R.layout.simple_spinner_dropdown_item);
type.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mainType.setAdapter(type);


String group=mainType.getSelectedItem().toString();

上述方法返回一个字符串值

在上面的R.array.admin_type是值中的字符串资源文件

只需在值>>字符串中创建一个.xml文件

假设你需要从资源的字符串数组中填充转轮,并且你想保持从服务器中选择的值。 这是在spinner中设置从server中选中的值的一种方法
pincodeSpinner.setSelection(resources.getStringArray(R.array.pincodes).indexOf(javaObject.pincode))
希望这对你有帮助! 另外,代码是在Kotlin!< / p >

如果将XML数组设置为XML布局中的旋转器,则可以做到这一点

final Spinner hr = v.findViewById(R.id.chr);
final String[] hrs = getResources().getStringArray(R.array.hours);
if(myvalue!=null){
for (int x = 0;x< hrs.length;x++){
if(myvalue.equals(hrs[x])){
hr.setSelection(x);
}
}
}

因为我需要一些东西,也适用于本地化,我想出了这两个方法:

    private int getArrayPositionForValue(final int arrayResId, final String value) {
final Resources english = Utils.getLocalizedResources(this, new Locale("en"));
final List<String> arrayValues = Arrays.asList(english.getStringArray(arrayResId));


for (int position = 0; position < arrayValues.size(); position++) {
if (arrayValues.get(position).equalsIgnoreCase(value)) {
return position;
}
}
Log.w(TAG, "getArrayPosition() --> return 0 (fallback); No index found for value = " + value);
return 0;
}
正如你所看到的,我还被arrays.xml和我正在比较的value之间的区分大小写的额外复杂性绊倒了。 如果你没有这个,上面的方法可以简化为:

return arrayValues.indexOf(value);

静态助手方法

public static Resources getLocalizedResources(Context context, Locale desiredLocale) {
Configuration conf = context.getResources().getConfiguration();
conf = new Configuration(conf);
conf.setLocale(desiredLocale);
Context localizedContext = context.createConfigurationContext(conf);
return localizedContext.getResources();
}

你可以使用这种方式,只是让你的代码更简单、更清晰。

ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinnerCountry.getAdapter();
int position = adapter.getPosition(obj.getCountry());
spinnerCountry.setSelection(position);

希望能有所帮助。