Android Spinner: Get the selected item change even

2019-01-01 02:55发布

问题:

How can you set the event listener for a Spinner when the selected item changes?

Basically what I am trying to do is something similar to this:

spinner1.onSelectionChange = handleSelectionChange;

void handleSelectionChange(Object sender){
    //handle event
}

回答1:

Some of the previous answers are not correct. They work for other widgets and views, but the documentation for the Spinner widget clearly states:

A spinner does not support item click events. Calling this method will raise an exception.

Better use OnItemSelectedListener() instead:

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        // your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // your code here
    }

});

This works for me.

Note that onItemSelected method is also invoked when the view is being build, so you can consider putting it inside onCreate() method call.



回答2:

Spinner spnLocale = (Spinner)findViewById(R.id.spnLocale);

spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { 
        // Your code here
    } 

    public void onNothingSelected(AdapterView<?> adapterView) {
        return;
    } 
}); 

Note: Remember one thing.

Spinner OnItemSelectedListener event will execute twice:

  1. Spinner initialization
  2. User selected manually

Try to differentiate those two by using flag variable.



回答3:

You can implement AdapterView.OnItemSelectedListener class in your Activity.

And then use the below line within onCreate()

Spinner spin = (Spinner) findViewById(R.id.spinner);
spin.setOnItemSelectedListener(this);

Then override these two methods:

public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
    selection.setText(items[position]);
}

public void onNothingSelected(AdapterView<?> parent) {
    selection.setText(\"\");
}


回答4:

https://stackoverflow.com/q/1714426/811625

You can avoid the OnItemSelectedListener() being called with a simple check: Store the current selection index in an integer variable and check within the onItemSelected(..) before doing anything.

E.g:

Spinner spnLocale;

spnLocale = (Spinner)findViewById(R.id.spnLocale);

int iCurrentSelection = spnLocale.getSelectedItemPosition();

spnLocale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { 
    if (iCurrentSelection != i){
            // Your code here
    }
    iCurrentSelection = i;
    } 

    public void onNothingSelected(AdapterView<?> adapterView) {
        return;
    } 
}); 

Of cause the iCurrentSelection should be in object scope for this to work!



回答5:

The docs for the spinner-widget says: \"A spinner does not support item click events.\" You should use \"setOnItemSelectedListener\" to handle your problem



回答6:

spinner1.setOnItemSelectedListener(
    new AdapterView.OnItemSelectedListener() {
        //add some code here
    }
);


回答7:

Find your spinner name and find id then implement this method.

spinnername.setOnItemSelectedListener(new OnItemSelectedListener() {

    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        // your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // your code here
    }
});


回答8:

take a global variable for current selection of spinner:

int currentItem = 0;

spinner_counter = (Spinner)findViewById(R.id.spinner_counter);
String[] value={\"20\",\"40\",\"60\",\"80\",\"100\",\"All\"};
aa=new ArrayAdapter<String>(this,R.layout.spinner_item_profile,value);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_counter.setAdapter(aa);

spinner_counter.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if(currentItem == position){
                return; //do nothing
            }
            else
            {
                 TextView spinner_item_text = (TextView) view;
                 //write your code here
            }
            currentItem = position;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

//R.layout.spinner_item_profile
<?xml version=\"1.0\" encoding=\"utf-8\"?>

<TextView  android:id=\"@+id/spinner_item_text\"
xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\" 
android:layout_height=\"wrap_content\"
android:background=\"@drawable/border_close_profile\"
android:gravity=\"start\"  
android:textColor=\"@color/black\"         
android:paddingLeft=\"5dip\"
android:paddingStart=\"5dip\"
android:paddingTop=\"12dip\"
android:paddingBottom=\"12dip\"
/>

//drawable/border_close_profile
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">
  <item>
   <shape android:shape=\"rectangle\">
    <solid android:color=\"#e2e3d7\" />
   </shape>
 </item>
<item android:left=\"1dp\"
android:right=\"1dp\"
android:top=\"1dp\"
android:bottom=\"1dp\">
<shape android:shape=\"rectangle\">
    <solid android:color=\"@color/white_text\" />
</shape>
</item>
</layer-list>


回答9:

It doesn\'t matter will you set OnItemSelectedListener in onCreate or onStart - it will still be called during of Activity creation or start (respectively).
So we can set it in onCreate (and NOT in onStart!).
Just add a flag to figure out first initialisation:

private Spinner mSpinner;
private boolean mSpinnerInitialized;

then in onCreate (or onCreateView) just:

mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                if (!mSpinnerInitialized) {
                    mSpinnerInitialized = true;
                    return;
                }

                // do stuff
            }

            public void onNothingSelected(AdapterView<?> adapterView) {
                return;
            }
        });


回答10:

If you want a true onChangedListener(). Store the initial value in the handler and check to see if it has changed. It is simple and does not require a global variable. Works if you have more than one spinner on the page.

String initialValue = // get from Database or your object
mySpinner.setOnItemSelectedListener(new SpinnerSelectedListener(initialValue));

...

protected class SpinnerSelectedListener implements AdapterView.OnItemSelectedListener {

        private SpinnerSelectedListener() {
            super();
        }

        public SpinnerSelectedListener(String initialValue) {
            this();
            this.initialValue = initialValue;
        }

        private String initialValue;

        // getter and setter removed.  

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            final String newValue = (String) spinHeight.getItemAtPosition(position);
            if (newValue.equals(initialValue) == false) {
               // Add your code here.  The spinner has changed value. 

               // Maybe useful.   
               // initialValue = newValue;
            }

        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
               // Maybe useful.   
               // initialValue = null; 
        }
    }

Objects are your friend, use them.



回答11:

spinner.setOnItemSelectedListener(
            new AdapterView.OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> arg0, View arg1,
                        int arg2, long arg3) {

                    // TODO Auto-generated method stub
                }

                @Override
                public void onNothingSelected(AdapterView<?> arg0) {
                    // TODO Auto-generated method stub

                }
                //add some code here
            }
        );


回答12:

Brilliant the above by Stefan Klumpp also helped me a lot. Thank you. I am a newbie and the \"@Override\"s in it caused an error about \"must override a Super class method of the same name\". Eclipse suggested I should remove the Overrides. When I did this, it worked. Please don\'t ask me how or why.



回答13:

The best way wht i think would be to have an flagitemselected=0; in oncreate. And on item selected event increment that flag i.e flagitemselected++; and then check if(flagitemselected!=1){// do your work here}.This will help i guess



回答14:

One trick I found was putting your setOnItemSelectedListeners in onWindowFocusChanged instead of onCreate. I haven\'t found any bad side-effects to doing it this way, yet. Basically, set up the listeners after the window gets drawn. I\'m not sure how often onWindowFocusChanged runs, but it\'s easy enough to create yourself a lock variable if you are finding it running too often.

I think Android might be using a message-based processing system, and if you put it all in onCreate, you may run into situations where the spinner gets populated after it gets drawn. So, your listener will fire off after you set the item location. This is an educated guess, of course, but feel free to correct me on this.