464

I am working on an android project and I am using a spinner which uses an array adapter which is populated from the database.

I can't find out how I can set the selected item programmatically from the list. For example if, in the spinner I have the following items:

  • Category 1
  • Category 2
  • Category 3

How would I programmatically make Category 2 the selected item when the screen is created. I was thinking it might be similar to c# I.E Spinner.SelectedText = "Category 2" but there doesn't seem to be any method similar to this for Android.

Sathyajith Bhat
  • 21,321
  • 22
  • 95
  • 134
Boardy
  • 35,417
  • 104
  • 256
  • 447
  • Please follow this link : [How to set selection on spinner item][1] [1]: http://stackoverflow.com/questions/16358563/how-to-maintain-spinner-state-in-android/23776382#23776382 – Maddy Sharma May 21 '14 at 07:18
  • 1
    You can pass your index into `spinner.setSelection()`. That would work just fine. You can also create a method that can help you match your indexes to their actual strings. – Taslim Oseni May 03 '19 at 11:05

25 Answers25

880

Use the following: spinnerObject.setSelection(INDEX_OF_CATEGORY2).

Arun George
  • 18,352
  • 4
  • 28
  • 28
  • 334
    Thanks, this worked great, while I was doing this I also found a way of getting the index without needing to loop through the adapter. I used the following ``mySpinner.setSelection(arrayAdapter.getPosition("Category 2"));`` – Boardy Jun 17 '12 at 16:01
  • 101
    in case you dont have the adapter to reference. mySpinner.setSelection(((ArrayAdapter)mySpinner.getAdapter()).getPosition("Value")); – Kalel Wade Apr 11 '14 at 17:10
  • 4
    sexSpinner.setSelection(adapter.getPosition(mUser.getGender()) == -1 ? 0 : adapter.getPosition(mUser.getGender())); – Goofyahead May 01 '14 at 09:06
  • calling SetSelection() just after setAdapter() seem to display the 1st item always (Android 2.3), even the good one is selected in the dropView. adding view.post() (@Marco Hernaiz Cao answer) fix it for me. – Christ Jun 20 '14 at 10:14
  • 7
    This doesn't work if the Spinner has an onItemSelectedListener(). The Listener won't be called. – Don Larynx May 17 '15 at 19:52
98

No one of these answers gave me the solution, only worked with this:

mySpinner.post(new Runnable() {
    @Override
    public void run() {
        mySpinner.setSelection(position);
    }
});
ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
Marco Hernaiz
  • 5,830
  • 3
  • 27
  • 27
  • 3
    I call SetSelection() just after setAdapter(). This display the 1st item always (Android 2.3), even the good one is selected in the dropView. Your solution did it for me. – Christ Jun 20 '14 at 10:14
  • 2
    Thanks, that worked! btw works for ListView.post.run() performItemClick() as well – Michael D. Aug 12 '14 at 13:30
  • How can I select the last one based on the size? – jvargas Mar 12 '20 at 17:11
46
public static void selectSpinnerItemByValue(Spinner spnr, long value) {
    SimpleCursorAdapter adapter = (SimpleCursorAdapter) spnr.getAdapter();
    for (int position = 0; position < adapter.getCount(); position++) {
        if(adapter.getItemId(position) == value) {
            spnr.setSelection(position);
            return;
        }
    }
}

You can use the above like:

selectSpinnerItemByValue(spinnerObject, desiredValue);

& of course you can also select by index directly like

spinnerObject.setSelection(index);
John Slegers
  • 45,213
  • 22
  • 199
  • 169
Yaqub Ahmad
  • 27,569
  • 23
  • 102
  • 149
  • An error with this code is that @Boardy want the selection of `Category 2` which I suppose is a String (assuming he tried using `Spinner.SelectedText = "Category 2"`) but the above code is for a `long`. – Arun George Jun 17 '12 at 15:47
  • He is populating the categories from the database there must be an ID for each category. – Yaqub Ahmad Jun 17 '12 at 15:50
  • 1
    Why assume it is a CursorAdapter? SpinnerAdapter works just as well. – Greg Ennis Aug 28 '13 at 23:03
  • I think you have a mistake here, it should be `adapter.getItem(position)`, not `adapter.getItemId(position)`. – Vadim Kotov Aug 02 '19 at 09:03
34

Some explanation (at least for Fragments - never tried with pure Activity). Hope it helps someone to understand Android better.

Most popular answer by Arun George is correct but don't work in some cases.
The answer by Marco HC uses Runnable wich is a last resort due to additional CPU load.

The answer is - you should simply choose correct place to call to setSelection(), for example it works for me:

@Override
public void onResume() {
    super.onResume();

    yourSpinner.setSelection(pos);
 }

But it won't work in onCreateView(). I suspect that is the reason for the interest to this topic.

The secret is that with Android you can't do anything you want in any method - oops:( - components may just not be ready. As another example - you can't scroll ScrollView neither in onCreateView() nor in onResume() (see the answer here)

Community
  • 1
  • 1
sberezin
  • 3,266
  • 23
  • 28
17

To find a value and select it:

private void selectValue(Spinner spinner, Object value) {
    for (int i = 0; i < spinner.getCount(); i++) {
        if (spinner.getItemAtPosition(i).equals(value)) {
            spinner.setSelection(i);
            break;
        }
    }
}
John Slegers
  • 45,213
  • 22
  • 199
  • 169
Ferran Maylinch
  • 10,919
  • 16
  • 85
  • 100
15

Why don't you use your values from the DB and store them on an ArrayList and then just use:

yourSpinner.setSelection(yourArrayList.indexOf("Category 1"));
David Bohunek
  • 3,181
  • 1
  • 21
  • 26
RicardoSousaDev
  • 893
  • 9
  • 9
  • 1
    The various solutions using the DataAdapter didn't work for me, but using the ArrayList that the values were built from in this sample did the trick. – ewall Jun 06 '16 at 00:30
13

The optimal solution is:

    public String[] items= new String[]{"item1","item2","item3"};
    // here you can use array or list 
    ArrayAdapter adapter= new ArrayAdapter(Your_Context, R.layout.support_simple_spinner_dropdown_item, items);
    final Spinner itemsSpinner= (Spinner) findViewById(R.id.itemSpinner);
itemsSpinner.setAdapter(adapter);

To get the position of the item automatically add the following statement

itemsSpinner.setSelection(itemsSpinner.getPosition("item2"));
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Naham Al-Zuhairi
  • 182
  • 3
  • 11
7

You can make a generic method for this kind of work as I do in my UtilityClass which is

public void SetSpinnerSelection(Spinner spinner,String[] array,String text) {
    for(int i=0;i<array.length;i++) {
        if(array[i].equals(text)) {
            spinner.setSelection(i);
        }
    }
}
John Slegers
  • 45,213
  • 22
  • 199
  • 169
ZygoteInit
  • 485
  • 6
  • 9
6

You can easily set like this: spinner.setSelection(1), instead of 1, you can set any position of list you would like to show.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
6

In Kotlin I found a simple solution using a lambda:

spinnerObjec.post {spinnerObjec.setSelection(yourIndex)}
  • There are twenty-four existing answers to this question, including an accepted answer with 843 (!!!) upvotes. Are you sure your answer hasn't already been provided? If not, why might someone prefer your approach over the existing approaches proposed? Are you taking advantage of new capabilities? Are there scenarios where your approach is better suited? – Jeremy Caney Nov 21 '21 at 21:48
5

I have a SimpleCursorAdapter so I have to duplicate the data for use the respose in this post. So, I recommend you try this way:

for (int i = 0; i < spinnerRegion.getAdapter().getCount(); i++) {
    if (spinnerRegion.getItemIdAtPosition(i) == Integer
        .valueOf(signal.getInt(signal
            .getColumnIndexOrThrow("id_region")))) {
        spinnerRegion.setSelection(i);
        break;
    }
}

I think that is a real way

pazfernando
  • 577
  • 6
  • 15
  • 1
    yes, in case of SimpleCursorAdapter, spinnerRegion.getItemIdAtPosition(i) gives a Cursor, which can be used to get the columns. – lalitm May 14 '14 at 07:26
4

This is what I use in Kotlin:

spinner.setSelection(resources.getStringArray(R.array.choices).indexOf("Choice 1"))
Donny Rozendal
  • 852
  • 9
  • 12
  • 1
    if `indexOf` can not make a match, then it returns `-1`, which appears to result in the default value being the selected by `spinner.setSelection`. I'm ok with that. – lasec0203 Sep 19 '19 at 07:06
3

I know that is already answered, but simple code to select one item, very simple:

spGenre.setSelection( ( (ArrayAdapter) spGenre.getAdapter()).getPosition(client.getGenre()) );
Dante
  • 742
  • 6
  • 10
3

This is work for me.

 spinner.setSelection(spinner_adapter.getPosition(selected_value)+1);
Arpit Patel
  • 7,212
  • 5
  • 56
  • 67
3

This is stated in comments elsewhere on this page but thought it useful to pull it out into an answer:

When using an adapter, I've found that the spinnerObject.setSelection(INDEX_OF_CATEGORY2) needs to occur after the setAdapter call; otherwise, the first item is always the initial selection.

// spinner setup...
spinnerObject.setAdapter(myAdapter);
spinnerObject.setSelection(INDEX_OF_CATEGORY2);

This is confirmed by reviewing the AbsSpinner code for setAdapter.

2

If you have a list of contacts the you can go for this:

((Spinner) view.findViewById(R.id.mobile)).setSelection(spinnerContactPersonDesignationAdapter.getPosition(schoolContact.get(i).getCONT_DESIGNATION()));
Maddy Sharma
  • 4,870
  • 2
  • 34
  • 40
2
  for (int x = 0; x < spRaca.getAdapter().getCount(); x++) {
            if (spRaca.getItemIdAtPosition(x) == reprodutor.getId()) {
                spRaca.setSelection(x);
                break;
            }
        }
1

Most of the time spinner.setSelection(i); //i is 0 to (size-1) of adapter's size doesn't work. If you just call spinner.setSelection(i);

It depends on your logic.

If view is fully loaded and you want to call it from interface I suggest you to call

spinner.setAdapter(spinner_no_of_hospitals.getAdapter());
spinner.setSelection(i); // i is 0 or within adapter size

Or if you want to change between activity/fragment lifecycle, call like this

spinner.post(new Runnable() {
  @Override public void run() {
    spinner.setSelection(i);
  }
});
Zeeshan
  • 1,625
  • 17
  • 25
1

Here is the Kotlin extension I am using:

fun Spinner.setItem(list: Array<CharSequence>, value: String) {
    val index = list.indexOf(value)
    this.post { this.setSelection(index) }
}

Usage:

spinnerPressure.setItem(resources.getTextArray(R.array.array_pressure), pressureUnit)
1

This Worked For me:

mySpinner.post(new Runnable() {
    @Override
    public void run() {
        mySpinner.setSelection(position);

        spinnerAdapter.notifyDataSetChanged();
    }
});
Anas Nadeem
  • 779
  • 6
  • 10
1

Yes, you can achieve this by passing the index of the desired spinner item in the setSelection function of spinner. For example:

spinnerObject.setSelection(INDEX_OF_CATEGORY).

0

In my case, this code saved my day:

public static void selectSpinnerItemByValue(Spinner spnr, long value) {
    SpinnerAdapter adapter = spnr.getAdapter();
    for (int position = 0; position < adapter.getCount(); position++) {
        if(adapter.getItemId(position) == value) {
            spnr.setSelection(position);
            return;
        }
    }
}
Juan Pablo
  • 1,213
  • 10
  • 15
  • You don't need to do this. adapter has a getPosition(item) call that returns int position. – tzg Apr 15 '19 at 15:09
0

I had made some extension function of Spinner for loading data and tracking item selection.

Spinner.kt

fun <T> Spinner.load(context: Context, items: List<T>, item: T? = null) {
    adapter = ArrayAdapter(context, android.R.layout.simple_spinner_item, items).apply {
        setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    }

    if (item != null && items.isNotEmpty()) setSelection(items.indexOf(item))
}

inline fun Spinner.onItemSelected(
    crossinline itemSelected: (
        parent: AdapterView<*>,
        view: View,
        position: Int,
        id: Long
    ) -> Unit
) {
    onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onNothingSelected(parent: AdapterView<*>?) {
        }

        override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
            itemSelected.invoke(parent, view, position, id)
        }
    }
}

Usaage Example

val list = listOf("String 1", "String 2", "String 3")
val defaultData = "String 2"

// load data to spinner
your_spinner.load(context, list, defaultData)

// load data without default selection, it points to first item
your_spinner.load(context, list)

// for watching item selection
your_spinner.onItemSelected { parent, view, position, id -> 
    // do on item selection
}
Sagar Chapagain
  • 1,683
  • 2
  • 16
  • 26
-1

This worked for me:

@Override
protected void onStart() {
    super.onStart();
    mySpinner.setSelection(position);
}

It's similar to @sberezin's solution but calling setSelection() in onStart().

JosinMC
  • 1
  • 2
-1

I had the same issue since yesterday.Unfortunately the first item in the array list is shown by default in spinner widget.A turnaround would be to find the previous selected item with each element in the array list and swap its position with the first element.Here is the code.

OnResume()
{
int before_index = ShowLastSelectedElement();
if (isFound){
      Collections.swap(yourArrayList,before_index,0);
   }
adapter = new ArrayAdapter<String>(CurrentActivity.this,
                            android.R.layout.simple_spinner_item, yourArrayList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item;                    yourListView.setAdapter(adapter);
}
...
private int ShowLastSelectedElement() {
        String strName = "";
        int swap_index = 0;
        for (int i=0;i<societies.size();i++){
            strName = yourArrayList.get(i);
            if (strName.trim().toLowerCase().equals(lastselectedelement.trim().toLowerCase())){
                swap_index = i;
                isFound = true;
            }
        }
        return swap_index;
    }