I have a spinner which I am showing in a dialog view, and the moment the dialog starts onItemSelected is called. I don't really want to process this but only when user makes the selection. So I either need to prevent this (maybe because no default value is set?), or I need to know it is not the user that is making this selection?
Another option in the spirit of Bill Mote's solution is to make the OnItemSelectedListener also an OnTouchListener. The user interaction flag can then be set to true in the onTouch method and reset in onItemSelected() once the selection change has been handled. I prefer this solution because the user interaction flag is handled exclusively for the spinner, and not for other views in the activity that may affect the desired behavior.
In code:
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);
You can simply add an int count to solve it :)
sp.setOnItemSelectedListener(new OnItemSelectedListener() {
int count=0;
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if(count >= 1){
int item = sp.getSelectedItemPosition();
Toast.makeText(getBaseContext(),
"You have selected the book: " + androidBooks[item],
Toast.LENGTH_SHORT).show();
}
count++;
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Beginning with API level 3 you can use onUserInteraction() on an Activity with a boolean to determine if the user is interacting with the device.
http://developer.android.com/reference/android/app/Activity.html#onUserInteraction()
@Override
public void onUserInteraction() {
super.onUserInteraction();
userIsInteracting = true;
}
As a field on the Activity I have:
private boolean userIsInteracting;
Finally, my spinner:
mSpinnerView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View view, int position, long arg3) {
spinnerAdapter.setmPreviousSelectedIndex(position);
if (userIsInteracting) {
updateGUI();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
As you come and go through the activity the boolean is reset to false. Works like a charm.
Androider, I have found a solution for this problem and posted it here (with code sample):
Spinner onItemSelected() executes when it is not suppose to
I have solved this problem a different way as I noticed sometimes the onItemSelected method was called twice on orientation change or sometimes once.
It seemed to depend on the current spinner selection. So a flag or counter didn't work for me. Instead I record the system time in BOTH onResume() and onCreate using widgetsRestartTime = System.currentTimeMillis()
widgetsRestartTime is declared as a double and as an intance variable.
Now in the onItemSelected() method I check the current time again and subtract widgetsRestartTime from it as follows: if (System.currentTimeMillis() - widgetsRestartTime > 200) { // user triggered event - so this is a real spinner event so process it } else { // system generated event e.g. orientation change, activity startup. so ignore }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With