androidspinnerrecreate

OnItemSelectedListener Spinner Recreate loop - Android


I have a spinner and when an item is selected i want to recreate the activity. But when the activity is recreated it keeps constantly recreating because the new itemSelectedListener is triggered. I have fixed the bug but i am interested in why this is happening. Thank you in advance for any insights you offer.

    sp_lang.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
               recreate();
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    });

Solution

  • You can avoid the first event with a flag in the OnItemSelectedListener.

    sp_lang.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    
            Boolean firstEventConsumed = false;
    
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                   if (firstEventConsumed) {
                       recreate();
                   } else {
                       firstEventConsumed = true;
                   }
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
    

    EDIT

    I have found a solution but it is just a workaround. It is not a definitive solution.

    It has a strange behaviour when you recreate the activity. When the activity is created for the first time, it doesn't call twice the onItemSelected, but when it is recreated it is called twice.

    What I have done below is to control when the item is selected by the user (handling the touch event) and when it is done by the activity.

    public class MainActivity extends AppCompatActivity {
    
        private Boolean isUserAction = false;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
    
            // get the spinner
            // create the adapter
            spinner.setAdapter(spinnerAdapter);
            spinner.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    isUserAction = true;
                    return false;
                }
            });
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                    if (isUserAction) {
                        recreate();
                    }
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {
                    // do nothing
                }
            });
        }
    }