Spinner: onItemSelected no se llama cuando el elemento seleccionado sigue siendo el mismo

Tengo un OnItemSelectedListener para mi Spinner , pero no se llama cuando el elemento seleccionado es el mismo que el anterior. Aparentemente, OnClickListener no es una opción para un Spinner . Necesito atrapar cada vez que un usuario hace clic en un elemento. ¿Alguna idea?

¿Tal vez el hecho de que este Spinner esté dentro de la ActionBar perturba el comportamiento normal?

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.tracklist_menu, menu); Spinner spinner = (Spinner) menu.findItem(R.id.option_ordering_spinner) .getActionView(); spinner.setAdapter(mSpinnerAdapter); spinner.setSelection(PrefsHelper.getOrderingSpinnerPos(prefs)); spinner.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { String str = "selected"; System.out.println(str); if (optionMenuInitialized) { switch (position) { case 0: // rdm getActivity() .sendBroadcast( new Intent( MyIntentAction.DO_RESHUFFLE_PLAYLIST)); smp.setCurrentTracklistCursorPos(-1); trackAdapter.notifyDataSetChanged(); break; case 1: // artist getActivity() .sendBroadcast( new Intent( MyIntentAction.DO_ORDER_PLAYLIST_BY_ARTIST)); smp.setCurrentTracklistCursorPos(-1); trackAdapter.notifyDataSetChanged(); break; case 2: // folder getActivity() .sendBroadcast( new Intent( MyIntentAction.DO_ORDER_PLAYLIST_BY_FOLDER)); smp.setCurrentTracklistCursorPos(-1); trackAdapter.notifyDataSetChanged(); break; } PrefsHelper.setOrderingSpinnerPos(prefEditor, position); prefEditor.commit(); } optionMenuInitialized = true; } @Override public void onNothingSelected(AdapterView parent) { } }); } 

Ok, finalmente encontré una solución, al crear mi propia clase extendiendo Spinner:

 public class MySpinner extends Spinner { OnItemSelectedListener listener; public MySpinner(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void setSelection(int position) { super.setSelection(position); if (listener != null) listener.onItemSelected(null, null, position, 0); } public void setOnItemSelectedEvenIfUnchangedListener( OnItemSelectedListener listener) { this.listener = listener; } } 

Descubrí este trabajo en lugar del proporcionado

 /** Spinner extension that calls onItemSelected even when the selection is the same as its previous value */ public class NDSpinner extends Spinner { public NDSpinner(Context context) { super(context); } public NDSpinner(Context context, AttributeSet attrs) { super(context, attrs); } public NDSpinner(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setSelection(int position, boolean animate) { boolean sameSelected = position == getSelectedItemPosition(); super.setSelection(position, animate); if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId()); } } @Override public void setSelection(int position) { boolean sameSelected = position == getSelectedItemPosition(); super.setSelection(position); if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId()); } } } 

Aquí una implementación un poco mejor:

 public class SpinnerPlus extends Spinner { AdapterView.OnItemSelectedListener listener; public SpinnerPlus(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void setSelection(int position) { super.setSelection(position); if (listener != null) listener.onItemSelected(this, getSelectedView(), position, 0); } public void setOnItemSelectedEvenIfUnchangedListener( AdapterView.OnItemSelectedListener listener) { this.listener = listener; } } 

Para hacer que su spinner cambie a pesar del valor del último índice seleccionado, simplemente use a:

 spinner.setSelection(0); 

antes de que se llame su otra selección

 spinner.setSelection(number); 

de esta manera, la ruleta activará dos veces el evento OnItemSelected . Solo asegúrate de que la segunda vez haga lo que necesites.

Si todavía es real, la llamada correcta de la callback debe ser

 @Override public void setSelection(int position) { super.setSelection(position); if(listener != null) listener.onItemSelected(this, getChildAt(position), position, 0); } 

Martín

La solución más simple:

spinner.performItemClick (ver, posición, id)