55

I'm having some problems with setSelection on a Spinner. I set the value to be pre-selected when the spinner is shown in code, but it has no effect and the first alternative in the list is always selected. The code looks like this:

LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View dialogView = li.inflate(R.layout.edit_event, null);
...
ArrayList<String> routes = new ArrayList<String>();
// routes filled with values at runtime
...
ArrayAdapter<String> aa = new ArrayAdapter<String>(GOFdroid.this, android.R.layout.simple_spinner_item, routes);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  
Spinner destSpinner = (Spinner) dialogView.findViewById(R.id.edit_event_destination);
  
String dest = events.get(pos).getDestination();
int routesPos = routes.indexOf(dest);
Log.d(TAG, "Dest: " + dest + ", pos: " + routesPos);
destSpinner.setSelection(routesPos);
   
destSpinner.setAdapter(aa);

The code works as intended except for the setSelection-part, and I just can't figure out why.

The XML layout of the spinner looks like this (not the entire layout, only the spinner part):

// DESTINATION
<TextView
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Destination:" />
<Spinner
   android:id="@+id/edit_event_destination"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:prompt="@string/choose_dest"
   android:layout_marginBottom="10dip"
   android:text="" />

Help is very much appreciated!

Ramesh R
  • 7,009
  • 4
  • 25
  • 38
aspartame
  • 4,622
  • 7
  • 36
  • 39

11 Answers11

141

Try moving the call to setSelection() after the call to setAdapter().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
74

I had similar problem. In my case setAdaper and setSelection were in correct order! Executed form onCreate worked, but when executed from onResume had no effect.

The solution is to call setSelection(my_pos, true). Notice the second parameter.

Greg Dan
  • 6,198
  • 3
  • 33
  • 53
  • 7
    Thanks ! I would have never imagine that a parameter named 'animate' would have this effect... – Timores Oct 12 '11 at 20:29
  • Thanks so much! I would not have tried that. I spent two hours on this before finding your post. – Paul Feb 16 '12 at 19:24
  • I also had the setselection in OnResume which didn't work. Using the second parameter as you indicated it does, but now the spinner is moved aways from the original position. – radhoo Mar 21 '12 at 09:23
  • 2
    Thanks a lot. I was beginning to think I am the problem. – Tawani Oct 20 '12 at 19:08
  • It seems like a bug in sdk, because still now only works for me the selection with this method... – Pelanes Jun 27 '13 at 16:12
  • 1
    On newer Android versions this 'bug' has been fixed, but if you support older devices you will be surprised :) btw setSelection(my_pos, false) also works fine .... – Gordon Freeman May 20 '15 at 10:17
  • Worked like a charm, thanks! I assume the "animate" displays the newly selected option, but can anyone provide some more information on why this is required? – shai tibber Sep 16 '17 at 06:19
  • Worked for me too..but don't know why it's working when animate becomes true.. ;) – Shailendra Madda Oct 25 '17 at 09:23
39

You might try

mSpinner.post(new Runnable() {        
    public void run() {
      mSpinner.setSelection(1);
    }
  });

this will post the runnable action to run as soon as the view is created

user2532906
  • 391
  • 3
  • 2
31

In my case none of the answers worked, so I queued the setSelection through a Handler

new Handler().postDelayed(new Runnable() {        
    public void run() {
      mSpinner.setSelection(1);
    }
  }, 100);

Doing this could cause problems when running on slow devices, but I'm working for a specific device so it's ok to use this hack

Maragues
  • 37,861
  • 14
  • 95
  • 96
4

None of the previous answers worked for me. What did work, though, was creating the instance variable mSpinner in the onCreateView() method of my fragment (or in the onCreate() method of your activity), then doing this in my onLoadFinished() method...

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    adapter.swapCursor(cursor);
    //mSpinner.setAdapter(adapter);
    mSpinner.setSelection(mSelectedIndex);
}
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
ban-geoengineering
  • 18,324
  • 27
  • 171
  • 253
  • Moving the Spinner & Adapter initialization into the onCreateView (Fragment), was enough for me to get it working in the "onResume()" override function – Sajid2405 Jun 28 '20 at 06:34
4

Spinner.setSelection() do not work if you call it before Spinner.setAdapter()

Try calling setSelection() after the call to setAdapter().

Reason Behind this : when you call Spinner.Selection() before setting an adapter to it simply means that you are trying to set spinner to custom index by setSelection() when it doesn't contain any data or we can say thats spinner has max item =0.

so setSelection(1) means setting index to 1 for spinner which has max item =0; Although spinner itself handles this outofBoundIndex so your app does not crashes.

call to SetSelection() should be after setAdapter() only

Also if you have a Spinner.SetOnItemSelectedListener() and you have problem that onItemSelected(AdapterView<?> parent, View view, int position, long id) is tiggered with position value=0 when activity load and then you should use this pattern.

Spinner.SetAdapter()
Spinner.setSelection();
Spinner.setOnItemSelectedListener();
saksham
  • 3,173
  • 1
  • 21
  • 23
1
The solution is to call setSelection(my_pos, true). Notice the second parameter.

Don`t forget, if you call animate, setup layout params then :) Example:

LinearLayout.LayoutParams spinnerLp = (LinearLayout.LayoutParams) spinner.getLayoutParams();
spinner.setSelection(selectedPositionAge, true);
spinnerLp.gravity = Gravity.CENTER;
spinner.setLayoutParams(spinnerLp);

manually set paddings to spinner need to be reset manually.

Ramesh R
  • 7,009
  • 4
  • 25
  • 38
1

I had the same problem with a spinner inside a fragment : setSelection works correctly during the onCreate at first start of the activity, but not when I rotate the screen. I solved it by calling setSelection within the onViewStateRestored method of the fragment instead of calling it inside the onCreate method. I'm not sure but I think that you can't use setSelection until the view is fully loaded, even if you can findViewById it.

DontVoteMeDown
  • 21,122
  • 10
  • 69
  • 105
piiiiipppp
  • 11
  • 1
  • This was the solution in my case. Basically, in `onCreate` that isn't the first one, the view state is then restored by the system. A `setSelection` in there will be reverted by the state restoration mechanism. The solution is to run `setSelection` after state restoration occurs – entropy Jul 07 '14 at 14:24
  • This looks promising but when I call `Spinner mySpinner = (Spinner)getView().findViewById(R.id.mySpinner);` within the `onViewStateRestored()` method, it returns null (and it doesn't return null when I call it in `onCreate()`). – ban-geoengineering Aug 02 '15 at 16:50
1

use this

sp2.setAdapter(sp2.getAdapter());
sp2.getAdapter().notifyDataSetChanged();
sp2.setSelection(0, false);
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Ali Bagheri
  • 3,068
  • 27
  • 28
0

try this, it worked for me:

Spinner destSpinner = (Spinner)dialogView.findViewById(R.id.edit_event_destination);
destSpinner.setSelection(0);
String dest = events.get(pos).getDestination();
int routesPos = routes.indexOf(dest);
destSpinner.setAdapter(aa);
Log.d(TAG, "Dest: " + dest + ", pos: " + routesPos);
destSpinner.setSelection(routesPos);
Tunaki
  • 132,869
  • 46
  • 340
  • 423
skandhan
  • 41
  • 1
0

Sometimes, we may not set listeners because the spinner may be set to a certain value, and disabled as per requirement.

This can lead to setSelection() not selecting a value, since it needs a listener.

Make sure that the Spinner's setOnItemSelectedListener() is set to a custom listener like below.

Even if the spinner is disabled, we must set a listener like below, so that the setSelection() method works.

spinnerListener.setOnItemSelectedListener(spinnerListener);
AdapterView.OnItemSelectedListener spinnerListener = new 
AdapterView.OnItemSelectedListener() 
{
    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
      //Your code
    }
}
spinnerListener.setSelection(0);
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
koushick
  • 157
  • 1
  • 8