Wie stelle ich das ausgewählte Element des Spinners nach Wert und nicht nach Position ein?


297

Ich habe eine Aktualisierungsansicht, in der ich den in der Datenbank gespeicherten Wert für einen Spinner vorwählen muss.

Ich hatte so etwas im Sinn, aber das Adapterhat keine indexOfMethode, also stecke ich fest.

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

Antworten:


646

Angenommen, Ihr SpinnerName ist benannt mSpinnerund enthält als eine seiner Optionen: "einen Wert".

Verwenden Sie Folgendes, um die Position von "einem Wert" im Spinner zu finden und zu vergleichen:

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

5
Mit einem benutzerdefinierten Adapter müssen Sie den Code für getPosition ()
Soham

3
Wie wäre es, wenn Sie nicht gegen eine Zeichenfolge, sondern gegen ein Element in einem Objekt prüfen und es nicht möglich ist, nur toString () zu verwenden, da der Wert des Drehfelds von der Ausgabe von toString () abweicht.
Ajibola

1
Ich weiß, dass dies sehr alt ist, aber dies wirft jetzt einen ungeprüften Aufruf an getPosition (T)
Brad Bass

hatte ähnliche Fehler geworfen, aber die Verwendung dieser alten Schule half: stackoverflow.com/questions/25632549/…
Manny265

Hmm ... Was ist nun, wenn ich den Wert beispielsweise von Parse.com abrufe und den Benutzer abfragen möchte, sodass die Standardauswahl für den Drehfeld standardmäßig den Datenbankwert des Benutzers verwendet?
Drearypanoramic

141

Eine einfache Möglichkeit, den Spinner basierend auf dem Wert einzustellen, ist

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

Weg zu komplexem Code gibt es schon, das ist nur viel einfacher.


7
Sie haben vergessen hinzuzufügen, break;wann der Index gefunden wurde, um den Prozess zu beschleunigen.
Spacebiker

Warum nicht do {} while () verwenden, um die Verwendung von break zu vermeiden?
Catluc

@Catluc gibt es n Möglichkeiten, um zu einer Lösung zu gelangen, wählen Sie ... was für Sie am besten funktioniert
Akhil Jain

4
Anstatt 0, sollten Sie zurückkommen, -1wenn der Wert nicht gefunden wird - wie in meiner Antwort gezeigt: stackoverflow.com/a/32377917/1617737 :-)
ban-Geoengineering

2
@ Ban-Geoengineering Ich habe 0als Backup-Szenario geschrieben. Wenn Sie festlegen -1, welches Element beim Drehfeld sichtbar sein soll, nimmt das 0-te Element des Drehfeldadapters an. Durch Hinzufügen von -1 wird auch die Übergewichtung der Überprüfung erhöht, ob der Wert -1 ist oder nicht. Die Einstellung -1 führt zu einer Ausnahme.
Akhil Jain

34

Ich führe eine separate ArrayList aller Elemente in meinen Spinnern. Auf diese Weise kann ich indexOf für die ArrayList ausführen und dann diesen Wert verwenden, um die Auswahl im Spinner festzulegen.


Es gibt keinen anderen Weg, wissen Sie?
Pentium10

1
Wie setze ich die Auswahl auf nichts? (wenn der Artikel nicht in der Liste ist)
Pentium10

5
HashMap.get würde eine bessere Suchgeschwindigkeit als ArrayList.indexOf
Dandre Allison

29

Basierend auf Merrills Antwort habe ich diese einzeilige Lösung gefunden ... sie ist nicht sehr hübsch, aber Sie können jedem, der den Code verwaltet, die Schuld geben, Spinnerdass er es versäumt hat, eine Funktion einzuschließen, die dies dafür tut.

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

Sie erhalten eine Warnung darüber, wie die Besetzung von a ArrayAdapter<String>deaktiviert ist ... Sie könnten wirklich eine ArrayAdapterwie Merrill verwenden, aber das tauscht nur eine Warnung gegen eine andere aus.


Um die ungeprüfte Warnung zu entfernen, sollten Sie <? > in Ihrer Besetzung anstelle von <String>. Tatsächlich sollten Sie jedes Mal, wenn Sie etwas mit einem Typ besetzen, <? >.
Xbakesx

Nein, wenn ich auf ein <? > Es wird ein Fehler anstelle einer Warnung ausgegeben: "Die Methode getPosition (?) vom Typ ArrayAdapter <?> gilt nicht für das Argument (String)."
ArtOfWarfare

Richtig, es wird dann denken, dass es sich um einen ArrayAdapter ohne Typ handelt, sodass nicht davon ausgegangen wird, dass es sich um einen ArrayAdapter <String> handelt. Um die Warnung zu vermeiden, müssen Sie sie in ArrayAdapter <umwandeln. > wandeln Sie dann das Ergebnis Ihrer adapter.get () in einen String um.
Xbakesx

@ Dadani - Ich nehme an, Sie haben Python noch nie zuvor verwendet, weil dies dumm verwickelt ist.
ArtOfWarfare

Einverstanden, ich habe nicht mit Python @ArtOfWarfare herumgespielt, aber dies ist ein schneller Weg für bestimmte Aufgaben.
Daniel Dut

13

Wenn Sie ein String-Array verwenden, ist dies der beste Weg:

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

10

Sie können dies auch verwenden,

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

Geniale Arbeit!
Sadman Hasan

8

Wenn Sie eine indexOf-Methode für einen alten Adapter benötigen (und die zugrunde liegende Implementierung nicht kennen), können Sie Folgendes verwenden:

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

7

Basierend auf Merrills Antwort ist hier, wie man mit einem CursorAdapter umgeht

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

6

Verwenden Sie die folgende Zeile, um den Wert auszuwählen:

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

3

Ich verwende einen benutzerdefinierten Adapter, dafür reicht dieser Code aus:

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

Ihr Code-Snippet sieht also folgendermaßen aus:

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

3

Dies ist meine einfache Methode, um den Index anhand einer Zeichenfolge abzurufen.

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

3

Sie können auf diese Weise Ihren Code einfacher und klarer gestalten.

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

Ich hoffe es hilft.


2

Hier ist meine Lösung

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

und getItemIndexById unten

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

Ich hoffe das hilft!


2

So geht's, wenn Sie a verwenden SimpleCursorAdapter(wo columnNameist der Name der Datenbankspalte, mit der Sie Ihre ausgefüllt haben 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;
    }
}

Auch (eine Verfeinerung von Akhils Antwort ) ist dies die entsprechende Methode, wenn Sie Ihren Spinner aus einem Array füllen:

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

1

Wenn Sie im XML-Layout ein XML-Array auf den Drehfeld setzen, können Sie dies tun

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

0

Es gibt tatsächlich eine Möglichkeit, dies mithilfe einer Indexsuche im AdapterArray zu erreichen, und all dies kann mit Reflexion erfolgen. Ich ging sogar noch einen Schritt weiter, da ich 10 Spinner hatte und diese dynamisch aus meiner Datenbank festlegen wollte und die Datenbank nur den Wert und nicht den Text enthält, da sich der Spinner tatsächlich von Woche zu Woche ändert, sodass der Wert meine ID-Nummer aus der Datenbank ist.

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

}

Hier ist die indizierte Suche, die Sie für fast jede Liste verwenden können, solange sich die Felder auf der obersten Objektebene befinden.

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

Die Cast-Methode, die hier für alle Grundelemente erstellt werden kann, ist eine für string und 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;
}

0

Um die Anwendung an die zuletzt ausgewählten Spinnerwerte zu erinnern, können Sie den folgenden Code verwenden:

  1. Der folgende Code liest den Spinnerwert und stellt die Spinnerposition entsprechend ein.

    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. Und geben Sie den folgenden Code ein, in dem Sie wissen, dass die neuesten Spinnerwerte vorhanden sind, oder wo erforderlich nach Bedarf. Dieser Code schreibt im Grunde den Spinner-Wert 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();

0

Ich hatte das gleiche Problem beim Versuch, das richtige Element in einem Spinner auszuwählen, der mit einem cursorLoader gefüllt wurde. Ich habe die ID des Elements abgerufen, das ich zuerst aus Tabelle 1 auswählen wollte, und dann einen CursorLoader verwendet, um den Spinner zu füllen. In onLoadFinished bin ich durch den Cursor gefahren, der den Adapter des Spinners aufgefüllt hat, bis ich das Element gefunden habe, das mit der ID übereinstimmt, die ich bereits hatte. Weisen Sie dann die Zeilennummer des Cursors der ausgewählten Position des Spinners zu. Es wäre schön, eine ähnliche Funktion zu haben, um die ID des Werts zu übergeben, den Sie im Drehfeld auswählen möchten, wenn Sie Details in ein Formular einfügen, das gespeicherte Drehfeldergebnisse enthält.

@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

}

0

Da einige der vorherigen Antworten sehr richtig sind, möchte ich nur sicherstellen, dass keiner von Ihnen in dieses Problem gerät.

Wenn Sie die Werte auf ArrayListusing setzen String.format, MÜSSEN Sie die Position des Werts mit derselben Zeichenfolgenstruktur ermitteln String.format.

Ein Beispiel:

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

Sie müssen die Position des benötigten Werts wie folgt ermitteln:

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

Andernfalls erhalten Sie den -1Artikel nicht gefunden!

Ich habe Locale.getDefault()wegen der arabischen Sprache verwendet .

Ich hoffe das wird für dich hilfreich sein.


0

Hier ist meine hoffentlich vollständige Lösung. Ich habe folgende Aufzählung:

public enum HTTPMethod {GET, HEAD}

wird in der folgenden Klasse verwendet

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

Code zum Festlegen des Drehfelds durch 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);

Wo R.id.spinnerHttpmethodist in einer Layout-Datei definiert und android.R.layout.simple_spinner_itemwird von Android-Studio geliefert.


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

Willkommen bei StackOverflow. Antworten, die nur Code enthalten, werden in der Regel zum Löschen markiert, da sie von "geringer Qualität" sind. Bitte lesen Sie den Hilfeabschnitt zur Beantwortung von Fragen und fügen Sie Ihrer Antwort einen Kommentar hinzu.
Graham

@ user2063903, Bitte fügen Sie Ihrer Antwort eine Erklärung hinzu.
LuFFy

0

sehr einfach nur benutzen getSelectedItem();

z.B :

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

Die obige Methode gibt einen Zeichenfolgenwert zurück

oben R.array.admin_typeist das eine String-Ressourcendatei in Werten

Erstellen Sie einfach eine XML-Datei in Werten >> Zeichenfolgen


0

Angenommen, Sie müssen den Spinner aus dem String-Array der Ressource füllen und den Wert vom Server ausgewählt lassen. Dies ist also eine Möglichkeit, einen ausgewählten Wert vom Server im Drehfeld festzulegen.

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

Ich hoffe es hilft! PS der Code ist in Kotlin!


0

Da ich etwas brauchte, das auch mit der Lokalisierung funktioniert , habe ich mir diese beiden Methoden ausgedacht:

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

Wie Sie sehen können, bin ich auch über die zusätzliche Komplexität der Groß- und Kleinschreibung zwischen arrays.xml und dem, mit dem valueich vergleiche , gestolpert . Wenn Sie dies nicht haben, kann die obige Methode wie folgt vereinfacht werden:

return arrayValues.indexOf(value);

Statische Hilfsmethode

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

-3

Sie müssen Ihren benutzerdefinierten Adapter mit einer Position wie REPEAT [Position] übergeben. und es funktioniert richtig.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.