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

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 à l'esprit quelque chose comme ça, mais l' Adapter n'a pas de méthode indexOf , donc je suis bloqué.

  • Problème avec une image de fond de mise en page
  • LibGDX. Dessiner un texte multiligne
  • Boîte de dialogue d'alerte depuis le service Android
  • ProgressBar sous ActionBar, comme la dernière mise à jour de l'application GMail
  • Android: quelle est la hiérarchie des vues?
  • IOS et Android Shared Linking Deep Linking?
  •  void setSpinner(String value) { int pos = getSpinnerField().getAdapter().indexOf(value); getSpinnerField().setSelection(pos); } 

    19 Solutions collect form web for “Comment définir l'élément sélectionné de Spinner par valeur, pas par position?”

    Supposons que votre Spinner s'appelle mSpinner , et il contient comme un de ses choix: "une certaine valeur".

    Pour trouver et comparer la position de «une certaine valeur» dans 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.equals(null)) { int spinnerPosition = adapter.getPosition(compareValue); mSpinner.setSelection(spinnerPosition); } 

    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) { int index = 0; for (int i=0;i<spinner.getCount();i++){ if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(myString)){ index = i; break; } } return index; } 

    La façon de compléter le code est déjà là, cela est très simple.

    Je conserve une liste ArrayList distincte de tous les éléments dans mes Spinners. De cette façon, je peux faire indexOf sur ArrayList, puis utiliser cette valeur pour définir la sélection dans le Spinner.

    Sur la base de la réponse de Merrill , j'ai trouvé cette solution à une seule ligne … ce n'est pas très joli, mais vous pouvez culpabiliser celui qui conserve le code pour Spinner pour négliger d'inclure une fonction qui fait cela pour cela.

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

    Vous recevrez un avertissement sur la façon dont le casting sur un ArrayAdapter<String> n'est pas ArrayAdapter<String> … En réalité, vous pouvez simplement utiliser un ArrayAdapter comme Merrill l'a fait, mais cela change simplement un avertissement pour un autre.

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

    Si vous devez disposer d'une méthode indexOf sur une ancienne Adaptateur (et vous ne connaissez pas l'implémentation sous-jacente), vous pouvez l'utiliser:

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

    Si vous utilisez un réseau de chaînes, c'est la meilleure façon:

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

    Vous pouvez l'utiliser également,

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

    Utilisez la ligne suivante pour sélectionner en utilisant la valeur:

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

    Voici comment le faire si vous utilisez un SimpleCursorAdapter (où columnName est le nom de la colonne db que vous avez utilisé 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); 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 } } 

    (Peut-être que vous devrez également fermer le curseur, selon que vous utilisez un chargeur.)

    Aussi (un raffinement de la réponse d' Akhil ) c'est la manière correspondante de le faire si vous remplissez votre Spinner 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 } }; 

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

    Il existe en fait une façon d'obtenir ceci en utilisant une recherche d'index sur AdapterArray et tout cela peut se faire avec réflexion. Je suis même allé un peu plus loin alors que j'avais 10 Spinners et je voulais les configurer dynamiquement dans ma base de données et la base de données ne contient que la valeur, mais pas le texte, alors que le Spinner change réellement 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 n'importe quelle liste 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 Cast qui peut être créée pour toutes les primitives ici est une pour la chaîne et l'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; } 

    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!

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

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

    Ainsi, votre extrait de code sera ainsi:

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

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

    1. Le code ci-dessous lit la valeur de la filière et définit la position de la centrifugeuse 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 le code ci-dessous où vous savez que les dernières valeurs de la filière sont présentes, ou ailleurs, au besoin. Ce 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(); 

    J'ai eu le même problème en essayant de sélectionner l'élément correct dans un spinner peuplé à l'aide d'un cursorLoader. J'ai récupéré l'identifiant de l'élément que je voulais sélectionner d'abord dans le tableau 1, puis utilisé un CursorLoader pour remplir le spinner. Dans le fichier OnLoadinished, j'ai parcouru le curseur en composant l'adaptateur de la filière jusqu'à ce que je trouvai l'élément correspondant à l'identifiant que j'avais déjà. Ensuite, assigné le numéro de ligne du curseur à la position sélectionnée de la filière. Il serait bon d'avoir une fonction similaire pour passer l'identifiant 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 } 

    Comme certaines des réponses précédentes sont très justes, je veux juste m'assurer que personne d'entre vous n'intervient avec ce problème.

    Si vous définissez les valeurs dans ArrayList aide de String.format , String.format DEVEZ obtenir la position de la valeur en utilisant la même structure 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 le poste de la valeur nécessaire comme ceci:

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

    Sinon, vous obtiendrez le -1 , élément introuvable!

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

    J'espère que cela vous sera utile.

    Voici ma solution esthétiquement complète. J'ai l'énoncé suivant:

     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 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 est défini dans un fichier de mise en page, et android.R.layout.simple_spinner_item est fourni par android-studio.

    Vous devez passer votre adaptateur personnalisé avec position comme REPEAT [position]. Et cela fonctionne correctement.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.