Odd Android Spinner behavior

2019-01-29 08:41发布

问题:

This is the code to populate my spinner.

The code:

String[] rcs = new String[review_cycles.length];
for (int i = 0; i < review_cycles.length; i++)
    rcs[i] = review_cycles[i].ReviewCycleName;
ArrayAdapter<String> rc_spinnerAdapter = new ArrayAdapter<String>(
        ActivityManagementReview.this,
        R.layout.simple_spinner_item, 
        rcs);
sp_review_cycle.setAdapter(rc_spinnerAdapter);
sp_review_cycle.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        DtoMrReviewCycleVersion selected_review_cycle_version = review_cycles[position];
        if (selected_review_cycle_version != latest_review_cycle_version) {
            latest_review_cycle_version = selected_review_cycle_version;
            int mr_version_id = latest_review_cycle_version.MrdVersionId;
            _URL_version = _url_base + "MrVersion/" + Integer.toString(mr_version_id);
            new GetMrVersionInfoAsyncTask().execute();
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        return;
    }
});

When I select a value from the spinner, the code is executed twice. Once with the selection I made and then right afterward, the first item in the list is executed again bringing me back to where I started.

How can I prevent this from happening?

Thanks.

回答1:

When I select a value from the spinner, the code is executed twice.

As I reminded you in the comments, Spinners call onItemSelected() when they load the default value. This feature is useful when you know about it, but since it is not what the average developer expects it is problematic as well.

The Spinner will also call onItemSelected() when the user re-selects the current value... When I want to avoid both of these false alarms I use something like this:

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    int previous = -1;
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if(previous != position && previous < -1) {
            Log.v("Example", "Selected: " + position);
            // Do something
        }
        previous = position;
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {}
});