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.
}
}
}
I might be answering too late over the post, however I managed to achieve this using Android Data binding library Android Databinding . I created a custom binding to make sure listener is not called until selected item is changed so even if user is selecting same position over and over again event is not fired.
Layout xml file
app:position
is where you are passing position to be selected.Custom binding
You can read more about custom data binding here Android Custom Setter
NOTE
Don't forget to enable databinding in your Gradle file
Include your layout files in
<layout>
tagsI 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.
After having had the same problem, I came to this solutions using tags. The idea behind it is simple: Whenever the spinner is changed programatically, make sure the tag reflects the selected position. In the listener then you check if the selected position equals the tag. If it does, the spinner selection was changed programatically.
Below is my new "spinner proxy" class:
You will also need an XML file with the tag setup in your
Values
directory. I named my filespinner_tag.xml
, but that's up to you. It looks like this:Now replace
in your code with
And make your handler somewhat look like this:
The function
isUiTriggered()
will return true if and only if the spinner has been changed by the user. Note that this function has a side effect - it will set the tag, so a second call in the same listener call will always returnfalse
.This wrapper will also handle the problem with the listener being called during layout creation.
Have fun, Jens.
The solution with a boolean flag or a counter didn't help me, 'cause during orientation change onItemSelected() calls "overflew" the flag or the counter.
I subclassed
android.widget.Spinner
and made tiny additions. The relevant parts are below. This solution worked for me.