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
}
}