[android] How to keep onItemSelected from firing off on a newly instantiated Spinner?

After having had the same problem, I came to this solutions using tags. The idea behind it is simple: Whenever the spinner is changed programatically, make sure the tag reflects the selected position. In the listener then you check if the selected position equals the tag. If it does, the spinner selection was changed programatically.

Below is my new "spinner proxy" class:

package com.samplepackage;

import com.samplepackage.R;
import android.widget.Spinner;

public class SpinnerFixed {

    private Spinner mSpinner;

    public SpinnerFixed(View spinner) {
         mSpinner = (Spinner)spinner;
         mSpinner.setTag(R.id.spinner_pos, -2);
    }

    public boolean isUiTriggered() {
         int tag = ((Integer)mSpinner.getTag(R.id.spinner_pos)).intValue();
         int pos = mSpinner.getSelectedItemPosition();
         mSpinner.setTag(R.id.spinner_pos, pos);
         return (tag != -2 && tag != pos);
    }

    public void setSelection(int position) {
        mSpinner.setTag(R.id.spinner_pos, position);
        mSpinner.setSelection(position);
    }

    public void setSelection(int position, boolean animate) {
        mSpinner.setTag(R.id.spinner_pos, position);
        mSpinner.setSelection(position, animate);
    }

    // If you need to proxy more methods, use "Generate Delegate Methods"
    // from the context menu in Eclipse.
}

You will also need an XML file with the tag setup in your Values directory. I named my file spinner_tag.xml, but that's up to you. It looks like this:

<resources xmlns:android="http://schemas.android.com/apk/res/android">
  <item name="spinner_pos" type="id" />
</resources>

Now replace

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

in your code with

SpinnerFixed myspinner;
...
myspinner = new SpinnerFixed(findViewById(R.id.myspinner));

And make your handler somewhat look like this:

myspinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if (myspinner.isUiTriggered()) {
            // Code you want to execute only on UI selects of the spinner
        }
    }

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

The function isUiTriggered() will return true if and only if the spinner has been changed by the user. Note that this function has a side effect - it will set the tag, so a second call in the same listener call will always return false.

This wrapper will also handle the problem with the listener being called during layout creation.

Have fun, Jens.

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to spinner

How to add a Hint in spinner in XML Hide Spinner in Input Number - Firefox 29 How can I use onItemSelected in Android? Show default value in Spinner in android Set selected item of spinner programmatically How to set Spinner Default by its Value instead of Position? How to change spinner text size and text color? WPF loading spinner How do I create an Android Spinner as a popup? How to add items to a spinner in Android?

Examples related to android-spinner

Change Spinner dropdown icon How to add a Hint in spinner in XML How to set dropdown arrow in spinner? How to customize a Spinner in Android Android Spinner : Avoid onItemSelected calls during initialization How to create a drop-down list? Best way to show a loading/progress indicator? Android : Fill Spinner From Java Code Programmatically How to change the spinner background in Android? How to set Spinner Default by its Value instead of Position?