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.
}
}
}
The use of Runnables is completely incorrect.
Use setSelection(position, false);
in the initial selection before setOnItemSelectedListener(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:
Spinner s = (Spinner)Util.findViewById(view, R.id.sound, R.id.spinner);
s.setAdapter(adapter);
s.setSelection(position, false);
s.setOnItemSelectedListener(listener);
Referring to the answer of Dan Dyer, try to register the OnSelectListener
in a post(Runnable)
method:
spinner.post(new Runnable() {
public void run() {
spinner.setOnItemSelectedListener(listener);
}
});
By doing that for me the wished behavior finally occurred.
In this case it also means that the listener only fires on a changed item.
I would have expected your solution to work -- I though the selection event would not fire if you set the adapter before setting up the listener.
That being said, a simple boolean flag would allow you to detect the rogue first selection event and ignore it.
I created a small utility method for changing Spinner
selection without notifying the user:
private void setSpinnerSelectionWithoutCallingListener(final Spinner spinner, final int selection) {
final OnItemSelectedListener l = spinner.getOnItemSelectedListener();
spinner.setOnItemSelectedListener(null);
spinner.post(new Runnable() {
@Override
public void run() {
spinner.setSelection(selection);
spinner.post(new Runnable() {
@Override
public void run() {
spinner.setOnItemSelectedListener(l);
}
});
}
});
}
It disables the listener, changes the selection, and re-enables the listener after that.
The trick is that calls are asynchronous to the UI thread, so you have to do it in consecutive handler posts.
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