Spinner's onItemSelected callback called twice after a rotation if non-zero position is selected

Managed to find a solution in another stackoverflow question:

spinner.post(new Runnable() {
    public void run() {
        spinner.setOnItemSelectedListener(listener);
    }
});

In general, there seem to be many events that trigger the onItemSelected call, and it is difficult to keep track of all of them. This solution allows you to only respond to user-initiated changes using an OnTouchListener.

Create your listener for the spinner:

public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener {

    boolean userSelect = false;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        userSelect = true;
        return false;
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        if (userSelect) { 
            // Your selection handling code here
            userSelect = false;
        }
    }

}

Add the listener to the spinner as both an OnItemSelectedListener and an OnTouchListener:

SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);

The first time the onItemSelected runs, the view is not yet inflated. The second time it is already inflated. The solution is to wrap methods inside onItemSelected with if (view != null).

@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
    if (view != null) { 
        //do things here

    }
}