Jak ustawić wybrany element Spinnera według wartości, a nie pozycji?

296

Mam widok aktualizacji, w którym muszę wstępnie wybrać wartość przechowywaną w bazie danych dla Spinnera.

Miałem na myśli coś takiego, ale Adapternie ma indexOfmetody, więc utknąłem.

void setSpinner(String value)
{
    int pos = getSpinnerField().getAdapter().indexOf(value);
    getSpinnerField().setSelection(pos);
}
Pentium10
źródło

Odpowiedzi:

644

Załóżmy, że twoja Spinnernazwa jest nazwana mSpinneri zawiera jedną z opcji: „jakaś wartość”.

Aby znaleźć i porównać pozycję „pewnej wartości” w Błystce, użyj tego:

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
źródło
5
z niestandardowym adapterem będziesz musiał napisać (przesłonić) kod dla getPosition ()
Soham
3
Co powiesz na to, że nie sprawdzasz względem łańcucha, ale element wewnątrz obiektu i nie można po prostu użyć toString (), ponieważ wartość pokrętła różni się od wyniku toString ().
Ajibola
1
Wiem, że to jest bardzo stare, ale teraz rzuca niesprawdzone wezwanie do getPosition (T)
Brad Bass
zgłoszono
Hmm ... Co teraz, jeśli pobieram wartość z, powiedzmy, Parse.com i chcę zapytać użytkownika, aby domyślny wybór pokrętła był domyślnie ustawiony na wartość bazy danych użytkownika?
drearypanoramic
141

Prostym sposobem ustawienia tarczy na podstawie wartości jest

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

Istnieje już sposób na skomplikowany kod, jest to o wiele prostsze.

Akhil Jain
źródło
7
Zapomniałeś dodać, break;gdy indeks zostanie znaleziony, aby przyspieszyć proces.
spacebiker
dlaczego nie użyć do {} while (), aby uniknąć przerwania?
Catluc,
@Catluc istnieje n sposobów na znalezienie rozwiązania, wybierasz ... co działa najlepiej dla Ciebie
Akhil Jain
4
Zamiast tego 0powinieneś zwrócić, -1jeśli wartość nie zostanie znaleziona - jak pokazano w mojej odpowiedzi: stackoverflow.com/a/32377917/1617737 :-)
ban-geoengineering
2
@ ban-geoengineering Napisałem 0jako scenariusz kopii zapasowej. Jeśli ustawisz -1, który element będzie widoczny na tarczy, przypuszczam, że 0. element adaptera tarczy, dodanie -1 dodaje również nadwagi sprawdzania, czy wartość wynosi -1, czy nie, ponieważ ustawienie -1 spowoduje wyjątek.
Akhil Jain,
34

Trzymam osobną listę ArrayList wszystkich elementów w moich Spinnerach. W ten sposób mogę wykonać indexOf na ArrayList, a następnie użyć tej wartości, aby ustawić wybór w Spinneru.

Mark B
źródło
Nie ma innego sposobu, wiesz o tym?
Pentium10
1
Jak ustawić wybór na nic? (jeśli pozycji nie ma na liście)
Pentium10
5
HashMap.get dałby lepszą szybkość wyszukiwania niż ArrayList.indexOf
Dandre Allison
29

Opierając się na odpowiedzi Merrill , wymyśliłem to rozwiązanie jednoliniowe ... nie jest zbyt ładne, ale możesz winić każdego, kto utrzymuje kod Spinnerza zaniedbanie włączenia funkcji, która to robi.

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

Otrzymasz ostrzeżenie o tym, jak ArrayAdapter<String>odznaczono rzutowanie na ... naprawdę, możesz po prostu użyć takiego, ArrayAdapterjak Merrill, ale to po prostu zamienia jedno ostrzeżenie na drugie.

ArtOfWarfare
źródło
Aby pozbyć się niesprawdzonego ostrzeżenia, powinieneś użyć <? > w obsadzie zamiast <String>. W rzeczywistości za każdym razem, gdy rzucisz cokolwiek na typ, powinieneś używać <? >.
xbakesx
Nie, jeśli rzucę na <? > zamiast ostrzeżenia pojawia się błąd: „Metoda getPosition (?) w typie ArrayAdapter <?> nie ma zastosowania do argumentu (String).”
ArtOfWarfare
Prawidłowo, pomyśli wtedy, że jest to ArrayAdapter bez żadnego typu, więc nie przyjmie, że jest to ArrayAdapter <String>. Aby uniknąć ostrzeżenia, musisz rzucić go na ArrayAdapter <? > następnie rzutuj wynik działania adapter.get () na String.
xbakesx
@Dadani - Rozumiem, że nigdy wcześniej nie korzystałeś z Pythona, ponieważ jest to głupio zawiłe.
ArtOfWarfare
Zgadzam się, nie grałem z Python @ArtOfWarfare, ale jest to szybki sposób na niektóre zadania.
Daniel Dut,
13

jeśli używasz tablicy ciągów, jest to najlepszy sposób:

int selectionPosition= adapter.getPosition("YOUR_VALUE");
spinner.setSelection(selectionPosition);
itzhar
źródło
10

Możesz użyć tego również,

String[] baths = getResources().getStringArray(R.array.array_baths);
mSpnBaths.setSelection(Arrays.asList(baths).indexOf(value_here));
PrvN
źródło
Genialna praca!
Sadman Hasan
8

Jeśli potrzebujesz metody indexOf na dowolnym starym adapterze (i nie znasz podstawowej implementacji), możesz użyć tego:

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;
}
xbakesx
źródło
7

Na podstawie odpowiedzi Merrill tutaj jest, jak zrobić z 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;
        }
    }
max4ever
źródło
6

Użyj następującej linii, aby wybrać wartość:

mSpinner.setSelection(yourList.indexOf("value"));
Faisal Shaikh
źródło
3

Używam niestandardowego adaptera, do tego wystarczy ten kod:

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

Tak więc fragment kodu będzie wyglądał następująco:

void setSpinner(String value)
    {
         yourSpinner.setSelection(arrayAdapter.getPosition(value));
    }
Miral Sarwar
źródło
3

To moja prosta metoda na uzyskanie indeksu przez ciąg znaków.

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;
}
aLIEz
źródło
3

Możesz użyć tego sposobu, po prostu uprość kod.

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

Mam nadzieję, że to pomoże.

azwar_akbar
źródło
2

oto moje rozwiązanie

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

i getItemIndexById poniżej

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

Mam nadzieję, że to pomoże!

Scott.N
źródło
2

Oto jak to zrobić, jeśli używasz SimpleCursorAdapter(gdzie columnNamejest nazwa kolumny db użytej do wypełnienia twojej 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);

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

Również (udoskonalenie odpowiedzi Akhila ) jest to odpowiedni sposób, aby to zrobić, jeśli wypełniasz swój Błystek z tablicy:

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
    }
};
zakaz geoinżynierii
źródło
1

Jeśli ustawisz tablicę XML na pokrętło w układzie XML, możesz to zrobić

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);
      }
   }
}
Lasitha Lakmal
źródło
0

Istnieje sposób na uzyskanie tego za pomocą wyszukiwania indeksów na AdapterArray, a wszystko to można zrobić za pomocą refleksji. Poszedłem nawet o krok dalej, ponieważ miałem 10 Spinnerów i chciałem ustawić je dynamicznie z mojej bazy danych, a baza danych przechowuje wartość nie tylko tekstu, ponieważ Spinner faktycznie zmienia się z tygodnia na tydzień, więc wartość jest moim numerem identyfikacyjnym z bazy danych.

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

}

Oto wyszukiwanie indeksowane, którego można użyć na prawie każdej liście, o ile pola znajdują się na najwyższym poziomie obiektu.

    /**
 * 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
}

Metoda rzutowania, którą można utworzyć dla wszystkich prymitywów tutaj, to metoda na łańcuch i 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;
}
JPM
źródło
0

Aby aplikacja zapamiętała ostatnio wybrane wartości pokrętła, możesz użyć poniższego kodu:

  1. Poniższy kod odczytuje wartość przędzarki i odpowiednio ustawia pozycję przędzarki.

    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. I umieść poniżej kodu, gdzie wiesz, że obecne są najnowsze wartości przędzarki, lub gdzieś indziej zgodnie z wymaganiami. Ten fragment kodu zasadniczo zapisuje wartość pokrętła w 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();
użytkownik3339073
źródło
0

Miałem ten sam problem, gdy próbowałem wybrać prawidłowy element w pokrętle wypełnionym za pomocą kursora. Pobrałem identyfikator elementu, który chciałem najpierw wybrać z tabeli 1, a następnie użyłem CursorLoader do wypełnienia pokrętła. W trybie onLoadFinished przewijałem kursor wypełniając adapter błystki, aż znalazłem element pasujący do identyfikatora, który już miałem. Następnie przypisał numer wiersza kursora do wybranej pozycji przędzarki. Byłoby miło mieć podobną funkcję do przekazywania identyfikatora wartości, którą chcesz wybrać w błystce podczas wypełniania szczegółów w formularzu zawierającym zapisane wyniki przędzarki.

@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

}
Jaz
źródło
0

Ponieważ niektóre z poprzednich odpowiedzi są bardzo poprawne, chcę się tylko upewnić, że nikt z was nie popełni takiego problemu.

Jeśli ustawisz wartości na ArrayListusing String.format, MUSISZ uzyskać pozycję wartości przy użyciu tej samej struktury ciągów String.format.

Przykład:

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

Musisz uzyskać pozycję o potrzebnej wartości w ten sposób:

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

W przeciwnym razie otrzymasz -1element, którego nie znaleziono!

Użyłem z Locale.getDefault()powodu języka arabskiego .

Mam nadzieję, że ci się przyda.

Mohammad AlBanna
źródło
0

Oto moje, mam nadzieję, kompletne rozwiązanie. Mam następujące wyliczenie:

public enum HTTPMethod {GET, HEAD}

używane w następującej klasie

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

Kod do ustawienia pokrętła według elementu enum HTTPMethod:

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

Gdzie R.id.spinnerHttpmethodjest zdefiniowany w pliku układu i android.R.layout.simple_spinner_itemjest dostarczany przez android-studio.

termigrator
źródło
0
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);
        }
    }
użytkownik2063903
źródło
Witamy w StackOverflow. Odpowiedzi zawierające tylko kod zwykle są oznaczane do usunięcia, ponieważ są „niskiej jakości”. Przeczytaj sekcję pomocy dotyczącą odpowiadania na pytania, a następnie rozważ dodanie komentarza do swojej odpowiedzi.
Graham,
@ user2063903, Dodaj wyjaśnienie w swojej odpowiedzi.
LuFFy,
0

bardzo prosty po prostu użyj getSelectedItem();

np .:

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

powyższa metoda zwraca wartość ciągu

powyżej R.array.admin_typeznajduje się plik zasobów łańcuchowych w wartościach

po prostu utwórz plik .xml w wartościach >> ciągach

ekspert komputerowy
źródło
0

Załóżmy, że musisz wypełnić pokrętło z tablicy łańcuchów z zasobu i chcesz zachować wybraną wartość z serwera. Jest to więc jeden ze sposobów ustawienia wybranej wartości z serwera w pokrętle.

pincodeSpinner.setSelection(resources.getStringArray(R.array.pincodes).indexOf(javaObject.pincode))

Mam nadzieję, że to pomoże! PS kod znajduje się w Kotlin!

hetsgandhi
źródło
0

Ponieważ potrzebowałem czegoś, co również działa z lokalizacją , wymyśliłem te dwie metody:

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

Jak widać, natknąłem się również na dodatkową złożoność rozróżniania wielkości liter między tablicami.xml a tymi, z valuektórymi się porównuję. Jeśli tego nie masz, powyższą metodę można uprościć do czegoś takiego:

return arrayValues.indexOf(value);

Metoda statycznego pomocnika

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();
    }
AZOM
źródło
-3

musisz przekazać niestandardowy adapter o pozycji takiej jak REPEAT [pozycja]. i działa poprawnie.

Urvi Jasani
źródło