Why is OnItemSelectedListener only called when an item changes, but not on every user selection?
Asked Answered
K

3

8

I'm using spinner controls in an Android application, and I handle user selections via an onItemSelectedListener() method. This seems to work okay when a different selection from the current one is made. I would like, under certain conditions to reset all spinners to default values and ensure that onItemSelectedListener() is called for all.

Is it part of Android's semantics that onItemSelectedListener() is only called when user selection changes. Is there a way to force onItemSelectedListener() to be called?

Keturahkeung answered 1/11, 2012 at 17:21 Comment(2)
Wait, you described the opposite of how a Spinner works. Spinners throw a RuntimeException when you use an OnItemClickListener and the OnItemSelectedListener is called regardless of whether the user re-selected the previous selection or made a new choice...Cesya
Thanks for the feedback, I misspelled. I am using onItemSelectedListemer(). I've now edited my message.Keturahkeung
D
3

The default Spinner doesn't trigger any event when you select the same item as your currently selected item. You will need to make a custom Spinner in order to do this. See How can I get an event in Android Spinner when the current selected item is selected again?

Dithyrambic answered 1/11, 2012 at 21:45 Comment(0)
S
12

If you want "onItemSelected" of Spinner to be fired, even if the item in the spinner is selected /if item selected and it is clicked again . Then use this custom class which extends spinner ,this worked for me

Then edit your activity with spinners like this , I changed

  static Spinner spinner1;

to

  static NDSpinner spinner1;

and

   variables.spinner1 = (Spinner) findViewById(R.id.spinner1); 

to

   variables.spinner1 = (NDSpinner ) findViewById(R.id.spinner1); 

Also I changed the xml layout where the spinner is located

    <Spinner
    android:id="@+id/spinner1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/place" />

to

    <com.yourpackagename.NDSpinner 
     android:id="@+id/spinner1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="@string/place" />

Spinner extension class:

 package com.yourpackagename;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.widget.Spinner;
 import android.widget.Toast;
 import java.lang.reflect.Field;

     /** Spinner extension that calls onItemSelected even when the selection is the same as       its previous value. 
       *   ie This is extended "Customized class of Spinner" to  get the "onItemSelected"      event even if the item in the
     *  Spinner is already  selected by the user*/
    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); }


      private void ignoreOldSelectionByReflection() {
            try {
                Class<?> c = this.getClass().getSuperclass().getSuperclass().getSuperclass();
                Field reqField = c.getDeclaredField("mOldSelectedPosition");
                reqField.setAccessible(true);
                reqField.setInt(this, -1);
            } catch (Exception e) {
                Log.d("Exception Private", "ex", e);
                // TODO: handle exception
            }
        }

      @Override
      public void  setSelection(int position, boolean animate)
      {
        boolean sameSelected = position == getSelectedItemPosition();
        ignoreOldSelectionByReflection();
        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) {
          ignoreOldSelectionByReflection();
          super.setSelection(position);
      }

    }
Swot answered 9/9, 2013 at 7:54 Comment(0)
D
3

The default Spinner doesn't trigger any event when you select the same item as your currently selected item. You will need to make a custom Spinner in order to do this. See How can I get an event in Android Spinner when the current selected item is selected again?

Dithyrambic answered 1/11, 2012 at 21:45 Comment(0)
S
0

Add the same adapter every time if you want to do it using default spinner :

@Override public void onItemSelected(AdapterView adapter, View v, int position, long lng) {

   spinner.setAdapter(adapter);

}
Schultz answered 1/4, 2020 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.