Comment définir l'élément sélectionné de Spinner par valeur, pas par position?


297

J'ai une vue de mise à jour, où je dois présélectionner la valeur stockée dans la base de données pour un Spinner.

J'avais en tête quelque chose comme ça, mais ça Adaptern'a pas de indexOfméthode, donc je suis coincé.

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

Réponses:


646

Supposons que votre Spinnersoit nommé mSpinneret qu'il contienne l'un de ses choix: "une certaine valeur".

Pour trouver et comparer la position de "une certaine valeur" dans le Spinner, utilisez ceci:

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
avec un adaptateur personnalisé, vous devrez écrire (remplacer) le code de getPosition ()
Soham

3
Que diriez-vous si vous ne comparez pas à une chaîne mais à un élément à l'intérieur d'un objet et qu'il n'est pas possible d'utiliser simplement toString () car la valeur du spinner varie de la sortie de toString ().
Ajibola

1
Je sais que c'est très ancien, mais cela lance maintenant un appel non contrôlé à getPosition (T)
Brad Bass

des erreurs similaires ont été lancées, mais l'utilisation de cette méthode à l'ancienne a aidé: stackoverflow.com/questions/25632549/…
Manny265

Hmm ... Maintenant, que se passe-t-il si je tire la valeur de, disons, Parse.com et que je souhaite interroger l'utilisateur afin que la sélection de spinner par défaut soit par défaut la valeur de la base de données de l'utilisateur?
drearypanoramic

141

Un moyen simple de définir le spinner en fonction de la valeur est

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

Il existe déjà du chemin vers du code complexe, c'est beaucoup plus simple.


7
Vous avez oublié d'ajouter break;lorsque l'index est trouvé pour accélérer le processus.
Spacebiker

pourquoi ne pas utiliser do {} while () pour éviter d'utiliser break?
Catluc

@Catluc, il existe de nombreuses façons d'arriver à une solution, vous choisissez ... ce qui vous
convient le

4
Au lieu de cela 0, vous devez retourner -1si la valeur n'est pas trouvée - comme indiqué dans ma réponse: stackoverflow.com/a/32377917/1617737 :-)
ban-geoengineering

2
@ ban-geoengineering J'ai écrit 0comme scénario de sauvegarde. Si vous définissez -1quel élément serait visible sur le spinner, je suppose que le 0ème élément de l'adaptateur spinner, l'ajout de -1 ajoute également un surpoids pour vérifier si la valeur est -1 ou non, car la définition de -1 entraînera une exception.
Akhil Jain, du

34

Je garde une liste de tableaux séparée de tous les éléments de mes Spinners. De cette façon, je peux faire indexOf sur ArrayList et ensuite utiliser cette valeur pour définir la sélection dans le Spinner.


Il n'y a pas d'autre moyen, vous savez?
Pentium10

1
Comment régler la sélection sur rien? (si l'article n'est pas dans la liste)
Pentium10

5
HashMap.get donnerait une meilleure vitesse de recherche que ArrayList.indexOf
Dandre Allison

29

Sur la base de la réponse de Merrill , j'ai trouvé cette solution à ligne unique ... ce n'est pas très joli, mais vous pouvez blâmer quiconque maintient le code pour Spinneravoir négligé d'inclure une fonction qui fait cela pour cela.

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

Vous obtiendrez un avertissement sur la façon dont la conversion en un ArrayAdapter<String>n'est pas cochée ... vraiment, vous pouvez simplement utiliser un ArrayAdaptercomme Merrill, mais cela échange simplement un avertissement contre un autre.


Pour vous débarrasser de l'avertissement non coché, vous devez utiliser <? > dans votre distribution au lieu de <String>. En fait, chaque fois que vous lancez quelque chose avec un type, vous devez utiliser <? >.
xbakesx

Non, si je lance un <? > il me donne une erreur au lieu d'un avertissement: "La méthode getPosition (?) dans le type ArrayAdapter <?> n'est pas applicable pour l'argument (String)."
ArtOfWarfare

Correct, il pensera alors que c'est un ArrayAdapter sans type, donc il ne supposera pas que c'est un ArrayAdapter <String>. Donc, pour éviter l'avertissement, vous devrez le convertir en ArrayAdapter <? > puis convertissez le résultat de votre adapter.get () en une chaîne.
xbakesx

@Dadani - Je suppose que vous n'avez jamais utilisé Python auparavant, car c'est stupidement alambiqué.
ArtOfWarfare

D'accord, je n'ai pas joué avec Python @ArtOfWarfare, mais c'est un moyen rapide pour certaines tâches.
Daniel Dut

13

si vous utilisez un tableau de chaînes, c'est la meilleure façon:

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

10

Vous pouvez également l'utiliser,

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

Un travail brillant!
Sadman Hasan

8

Si vous avez besoin d'une méthode indexOf sur n'importe quel ancien adaptateur (et que vous ne connaissez pas l'implémentation sous-jacente), vous pouvez utiliser ceci:

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

Sur la base de la réponse de Merrill, voici comment faire avec un 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;
        }
    }

6

Utilisez la ligne suivante pour sélectionner à l'aide de la valeur:

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

3

J'utilise un adaptateur personnalisé, pour cela ce code suffit:

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

Ainsi, votre extrait de code sera comme ceci:

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

3

Ceci est ma méthode simple pour obtenir l'index par chaîne.

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

Vous pouvez utiliser cette méthode, rendez votre code plus simple et plus clair.

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

J'espère que ça aide.


2

voici ma solution

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

et getItemIndexById ci-dessous

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

J'espère que cette aide!


2

Voici comment le faire si vous utilisez un SimpleCursorAdapter(où columnNameest le nom de la colonne db que vous avez utilisée pour remplir votre 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;
    }
}

Aussi (un raffinement de la réponse d' Akhil ), c'est la façon correspondante de le faire si vous remplissez votre Spinner à partir d'un tableau:

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

Si vous définissez un tableau XML sur le spinner dans la disposition XML, vous pouvez le faire

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

Il existe en fait un moyen d'obtenir cela en utilisant une recherche d'index sur AdapterArray et tout cela peut être fait avec réflexion. Je suis même allé plus loin car j'avais 10 Spinners et je voulais les définir dynamiquement à partir de ma base de données et la base de données ne contient que la valeur, pas le texte car le Spinner change en fait de semaine en semaine, donc la valeur est mon numéro d'identification de la base de données.

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

}

Voici la recherche indexée que vous pouvez utiliser sur presque toutes les listes tant que les champs sont au niveau supérieur de l'objet.

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

La méthode de conversion qui peut être créée pour toutes les primitives en est une pour string et 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

Pour que l'application se souvienne des dernières valeurs de spinner sélectionnées, vous pouvez utiliser le code ci-dessous:

  1. Le code ci-dessous lit la valeur du spinner et définit la position du spinner en conséquence.

    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. Et mettez ci-dessous le code où vous savez que les dernières valeurs de spinner sont présentes, ou ailleurs si nécessaire. Ce morceau de code écrit essentiellement la valeur de spinner dans 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

J'ai eu le même problème lors de la tentative de sélection de l'élément correct dans un spinner rempli à l'aide d'un curseur. J'ai récupéré l'ID de l'élément que je voulais d'abord sélectionner dans le tableau 1, puis j'ai utilisé un CursorLoader pour remplir le spinner. Dans onLoadFinished, j'ai parcouru le curseur en remplissant l'adaptateur du spinner jusqu'à ce que je trouve l'élément correspondant à l'ID que j'avais déjà. Ensuite, affectez le numéro de ligne du curseur à la position sélectionnée du spinner. Ce serait bien d'avoir une fonction similaire pour passer l'id de la valeur que vous souhaitez sélectionner dans le spinner lors du remplissage des détails sur un formulaire contenant des résultats de spinner enregistrés.

@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

Comme certaines des réponses précédentes sont très bonnes, je veux juste m'assurer qu'aucun d'entre vous ne tombe dans ce problème.

Si vous définissez les valeurs sur ArrayListusing String.format, vous DEVEZ obtenir la position de la valeur en utilisant la même structure de chaîne String.format.

Un exemple:

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

Vous devez obtenir la position de valeur requise comme ceci:

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

Sinon, vous obtiendrez l' -1article non trouvé!

J'ai utilisé à Locale.getDefault()cause de la langue arabe .

J'espère que cela vous sera utile.


0

Voici ma solution, espérons-le, complète. J'ai l'énumération suivante:

public enum HTTPMethod {GET, HEAD}

utilisé dans la classe suivante

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

Code pour définir le spinner par membre 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);

R.id.spinnerHttpmethodest défini dans un fichier de mise en page et android.R.layout.simple_spinner_itemfourni par android-studio.


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

Bienvenue dans StackOverflow. Les réponses contenant uniquement du code ont tendance à être signalées pour suppression car elles sont de «faible qualité». Veuillez lire la section d'aide sur la réponse aux questions, puis envisagez d'ajouter des commentaires à votre réponse.
Graham

@ user2063903, veuillez ajouter des explications dans votre réponse.
LuFFy

0

très simple il suffit d'utiliser getSelectedItem();

par exemple :

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

la méthode ci-dessus renvoie une valeur de chaîne

ci-dessus R.array.admin_typeest un fichier de ressources de chaîne dans les valeurs

il suffit de créer un fichier .xml dans les valeurs >> chaînes


0

Supposons que vous ayez besoin de remplir le spinner du tableau de chaînes de la ressource et que vous souhaitiez conserver la valeur sélectionnée sur le serveur. Donc, c'est une façon de définir la valeur sélectionnée du serveur dans le spinner.

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

J'espère que ça aide! PS le code est en Kotlin!


0

Puisque j'avais besoin de quelque chose, qui fonctionne également avec la localisation , j'ai trouvé ces deux méthodes:

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

Comme vous pouvez le voir, je suis également tombé sur une complexité supplémentaire de la sensibilité à la casse entre les tableaux.xml et ceux que valueje compare. Si vous ne l'avez pas, la méthode ci-dessus peut être simplifiée en quelque chose comme:

return arrayValues.indexOf(value);

Méthode d'assistance statique

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

vous devez passer votre adaptateur personnalisé avec une position comme REPEAT [position]. et cela fonctionne correctement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.