I've thought of some less than elegant ways to solve this, but I know I must be missing something.
My onItemSelected
fires off immediately without any interaction with the user, and this is undesired behavior. I wish for the UI to wait until the user selects something before it does anything.
I even tried setting up the listener in the onResume()
, hoping that would help, but it doesn't.
How can I stop this from firing off before the user can touch the control?
public class CMSHome extends Activity {
private Spinner spinner;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Heres my spinner ///////////////////////////////////////////
spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.pm_list, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
};
public void onResume() {
super.onResume();
spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
}
public class MyOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
Intent i = new Intent(CMSHome.this, ListProjects.class);
i.putExtra("bEmpID", parent.getItemAtPosition(pos).toString());
startActivity(i);
Toast.makeText(parent.getContext(), "The pm is " +
parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
}
}
Since nothing worked for me, and I have more than 1 spinner in my view (and IMHO holding a bool map is an overkill) I use the tag to count the clicks :
The use of Runnables is completely incorrect.
Use
setSelection(position, false);
in the initial selection beforesetOnItemSelectedListener(listener)
This way you set your selection with no animation which causes the on item selected listener to be called. But the listener is null so nothing is run. Then your listener is assigned.
So follow this exact sequence:
I have done with simplest way:
onCreate();
Done
if you need to recreate activity on the fly eg: changing themes , a simple flag/counter wont work
use onUserInteraction() function to detect user activity,
reference : https://stackoverflow.com/a/25070696/4772917
I have had LOTS of issues with the spinner firing of when I didn't want to, and all the answers here are unreliable. They work - but only sometimes. You will eventually run into scenarios where they will fail and introduce bugs into your code.
What worked for me was to store the last selected index in a variable and evaluate it in the listener. If it is the same as the new selected index do nothing and return, else continue with the listener. Do this:
Trust me when I say this, this is by far the most reliable solution. A hack, but it works!
My small contribution is a variation on some of the above that has suited me a few times.
Declare an integer variable as a default value (or last used value saved in preferences). Use spinner.setSelection(myDefault) to set that value before the listener is registered. In the onItemSelected check whether the new spinner value equals the value you assigned before running any further code.
This has the added advantage of not running code if the user selects the same value again.