Skip to content Skip to sidebar Skip to footer

Spinner's Onitemselected Callback Called Twice After A Rotation If Non-zero Position Is Selected

When I create my activity, I setup a Spinner, assigning it a listener and an initial value. I know that the onItemSelected callback is called automatically during application initi

Solution 1:

Managed to find a solution in another stackoverflow question:

spinner.post(new Runnable() {
    publicvoidrun() {
        spinner.setOnItemSelectedListener(listener);
    }
});

Solution 2:

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:

publicclassSpinnerInteractionListenerimplementsAdapterView.OnItemSelectedListener, View.OnTouchListener {

    booleanuserSelect=false;

    @OverridepublicbooleanonTouch(View v, MotionEvent event) {
        userSelect = true;
        returnfalse;
    }

    @OverridepublicvoidonItemSelected(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:

SpinnerInteractionListenerlistener=newSpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);

Solution 3:

Just use setSelection(#, false) before setting the listener:

@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
    ...
    spinner.setSelection(2, false);
    spinner.setOnItemSelectedListener(this);
}

The key is the second parameter. It says to not animate the transition, executing the action immediately and preventing onItemSelected from being fired twice, because a call is already made by the system.

Solution 4:

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).

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

    }
}

Solution 5:

This is what i did:

Do a local variable

BooleanchangeSpinner=true;

On the saveInstanceMethod save the selected item position of the spinner

@OverridepublicvoidonSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("ItemSelect",mySpinner.getSelectedItemPosition());
}

Then on the activity created get that int from savedInstanceState and if the int is != 0 then set the boolean variable on false;

@OverridepublicvoidonActivityCreated(Bundle savedInstanceState) {

    if (savedInstanceState!=null) {
        if (savedInstanceState.getInt("ItemSelect")!=0) {
           changeSpinner = false;
        }
    }

}

And for last on the OnItemSelected from the spinner do this

mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    publicvoidonItemSelected(AdapterView<?> parent,android.view.View v, int position, long id) {
        if (changeSpinner) {
           [...]
        } else {
           changeSpinner= true;
        }
    });

So, the first time when is called is not going to do anything, just make the boolean variable true, and the second time is going to execute the code. Maybe not the best solution but it work.

Post a Comment for "Spinner's Onitemselected Callback Called Twice After A Rotation If Non-zero Position Is Selected"