Just wondering how you handle the following problem: a result is calculated depending on two spinners' selected items. To handle the UI things, i.e. a user picks a new item in one of the spinners, I install a listener using setOnItemSelectedListener
for the spinner in my onCreate()
method of the activity.
Now: that works, of course, fine. The listener's work is to trigger a new calculation of the result.
The problem: because I intercept onPause()
onResume()
to save/restore the last state, I got a method that sets these two spinners' selected item programmatically like in here:
startSpinner.setSelection(pStart);
destSpinner.setSelection(pDest);
These two calls invoke the listeners, too! My calculation method for the result plus the notification of a new result set is invoked twice here!
A stupid direct approach for this would be to have a boolean variable disabling whatever the listener does inside, setting it before setting the selected items and resetting it afterwards. Okay. But is there a better method??
I don't want listeners to be called by code - actions, only by user actions! :-(
How do you do it? Thanks!
A cleaner solution, in my opinion, to differentiate between programmatic and user-initiated changes is the following:
Create your listener for the spinner as both an OnTouchListener and OnItemSelectedListener
Add the listener to the spinner registering for both event types
This way, any unexpected calls to your handler method due to initialization or re-initialization will be ignored.
Add the
OnItemSelectedListener
for each spinner after you have set any previous value inonResume
.I have an easier, and I think, better solution. Since I had to refresh the spinners even after initialization, this is a more generic approach. Please refer the accepted answer:
Undesired onItemSelected calls
Spinner.setSelection(int position, boolean animate) does trigger the listener on 4.3
It is very easy you can call the
Spinner.setSelection(int position, boolean animate)
method withfalse
so the listeners will not react on the change.When Spinner.setSelection(position) is used, it always activates setOnItemSelectedListener()
To avoid firing the code twice I use this solution:
This solution is valid when you are sure that Spinner.setSelection(position) us used. Also, it is important to set mIsSpinnerFirstCall=true each time before using Spinner.setSelection(position)