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!
My solution is very easy. First initialize a global boolean variable.
Then use below code in your onCreate() method.
Now you can use the setSelection method in everwhere without invoking the onItemSelected() method by below code.
I created a library that help for all, that no need to call item onClick action in Spinner For example:
where withAction is a boolean flag, that used for call or not item action
Link on Github: https://github.com/scijoker/spinner2
First add boolean values for stopping spinner listener call
Then you add on Touch listener and on Item click Listener Like below code
Its simple working good for stopping server call multiple times.
Okay, I got it working the way I want to now.
The thing to understand here (and I did not when I was writing that question...) is that everything in Android runs in one thread - the UI thread.
Meaning: even though you set Spinner's values here and there: they are only updated (visually) and their listeners are only called after all methods you're currently in (like
onCreate
,onResume
or whatever) are finished.This allows the following:
currentPos1
,currentPos2
)onItemSelectedListener()
call a method likerefreshMyResult()
or whatever.The
refreshMyResult()
method looks like this:Because the listeners will be called later - and by then, the remembered position in currentPos is already updated - nothing will happen and no unnecessary update of anything else will take place. When a user selects a new value in one of the spinners, well - the update will be performed accordingly!
That's it! :-)
Ahh - one more thing: the answer to my question is: No. The listeners cannot be disabled (easily) and will be called whenever a value is changed.