Как установить выбранный элемент счетчика по значению, а не по позиции?
у меня есть представление обновления, где мне нужно предварительно выбрать значение, хранящееся в базе данных для счетчика.
Я имел в виду что-то вроде этого, но Adapter
нет indexOf
метод, так что я застрял.
void setSpinner(String value)
{
int pos = getSpinnerField().getAdapter().indexOf(value);
getSpinnerField().setSelection(pos);
}
21 ответ:
Предположим ваш
Spinner
называетсяmSpinner
, и он содержит в качестве одного из своих вариантов: "некоторое значение".чтобы найти и сравнить положение "некоторого значения" в спиннере используйте это:
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); }
простой способ установить счетчик на основе значения
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; }
путь к сложному коду уже есть, это просто намного проще.
Я держу отдельный ArrayList всех элементов в моих блеснах. Таким образом, я могу сделать indexOf в ArrayList, а затем использовать это значение для установки выбора в Spinner.
на основе ответ Меррилла, Я придумал это однострочное решение... это не очень красиво, но вы можете обвинить того, кто поддерживает код для
Spinner
за пренебрежение включить функцию, которая делает это для того.mySpinner.setSelection(((ArrayAdapter<String>)mySpinner.getAdapter()).getPosition(myString));
вы получите предупреждение о том, как бросают в
ArrayAdapter<String>
снят... действительно, Вы могли бы просто использоватьArrayAdapter
как и Меррилл, но это просто меняет одно предупреждение на другое.
Если вы используете массив строк это лучший способ:
int selectionPosition= adapter.getPosition("YOUR_VALUE"); spinner.setSelection(selectionPosition);
Если вам нужно иметь метод 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; }
на основе ответа Меррилла вот как это сделать с 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; } }
вы также можете использовать это,
String[] baths = getResources().getStringArray(R.array.array_baths); mSpnBaths.setSelection(Arrays.asList(baths).indexOf(value_here));
используйте следующую строку, чтобы выбрать using value:
mSpinner.setSelection(yourList.indexOf("value"));
Это мой простой метод, чтобы получить индекс по строке.
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; }
Я использую пользовательский адаптер, для этого достаточно этого кода:
yourSpinner.setSelection(arrayAdapter.getPosition("Your Desired Text"));
Итак, ваш фрагмент кода будет выглядеть так:
void setSpinner(String value) { yourSpinner.setSelection(arrayAdapter.getPosition(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 } }
(возможно, Вам также нужно будет закрыть курсор, в зависимости от того, используете ли вы загрузчик.)
также (уточнение ответ Ахила) это соответствующий способ сделать это, если вы заполняете спиннер из массива:
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 } };
вот мое решение
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; }
надеюсь, что это поможет!
на самом деле есть способ получить это с помощью индексного поиска на AdapterArray, и все это можно сделать с отражением. Я даже пошел на один шаг дальше, так как у меня было 10 прядильщиков и хотел установить их динамически из моей базы данных, и база данных содержит значение только не текст, так как прядильщик фактически меняет неделю на неделю, поэтому значение-это мой идентификационный номер из базы данных.
// 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 }
метод 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; }
чтобы приложение запомнило последние выбранные значения счетчика, вы можете использовать следующий код:
ниже код считывает значение счетчика и устанавливает положение счетчика соответственно.
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; }
и поместите ниже код, где вы знаете, что последние значения spinner присутствуют, или где-то еще по мере необходимости. Этот фрагмент кода в основном записывает значение 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();
У меня была такая же проблема при попытке выбрать правильный элемент в spinner, заполненный с помощью cursorLoader. Я извлек идентификатор элемента, который я хотел выбрать сначала из таблицы 1, а затем использовал CursorLoader для заполнения счетчика. В onLoadFinished я прокрутил курсор, заполняющий адаптер spinner, пока не нашел элемент, который соответствовал идентификатору, который у меня уже был. Затем назначается номер строки курсора для выбранной позиции счетчика. Было бы неплохо иметь подобный функция для передачи идентификатора значения, которое вы хотите выбрать в spinner при заполнении сведений о форме, содержащей сохраненные результаты spinner.
@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 }
как некоторые предыдущие ответы очень правильные, я просто хочу убедиться, что ни один из вас попадет в такую проблему.
если вы установите значения
ArrayList
используяString.format
, вы должны получить позицию значения, используя ту же строковую структуру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()
из-за английский язык.Я надеюсь, что будет полезно для вас.
вот мое, надеюсь, полное решение. У меня есть следующие перечисления:
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-файл в значениях> > строки