Android Spinner onItemSelected runs twice when returning to fragment

I created a spinner for my fragment that populates it with data retrieved from the HTTP callout. When the Fragment is first created, I populate the counter with my selections, set its setOnItemSelectedListener and set its initial selection to onCreateView ().

stateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (spinnerPosition != position) { spinnerPosition = position; TextView stateSelected = (TextView) view; String stateSelectedStr = stateSelected.getText().toString(); LinearLayout ballotsDisplay = (LinearLayout) getActivity().findViewById(R.id.ballotsDisplay); ballotsDisplay.removeAllViews(); Map<String, String> calloutParams = new HashMap<String, String>(); calloutParams.put("state", stateSelectedStr); // Create and execute AsyncTask to retrieve ballots new RetrieveBallots().execute(calloutParams); } } public void onNothingSelected(AdapterView<?> parent) { return; } }); // Set default selection for spinner int defaultState = adapter.getPosition(userState); if (defaultState == -1) { defaultState = 0; } stateSpinner.setSelection(defaultState); 

When the Fragment is created, everything works well, the turn signal position is set to the default value, and the spinner element is selected once, as shown in the log below:

 5009-5009/com.project.test D/TEST﹕ onCreateView called 5009-5009/com.project.test D/TEST﹕ stateSpinner.setSelection 5009-5009/com.project.test D/TEST﹕ onActivityCreated called 5009-5009/com.project.test D/TEST﹕ onResume called 5009-5009/com.project.test D/TEST﹕ spinner item selected 

The problem occurs when I move from fragment to another fragment (I store the fragment on the backstack). When I click back to return to my original fragment, the counter seems to have its element selected twice:

 5009-5009/com.project.test D/TEST﹕ onCreateView called 5009-5009/com.project.test D/TEST﹕ stateSpinner.setSelection 5009-5009/com.project.test D/TEST﹕ onActivityCreated called 5009-5009/com.project.test D/TEST﹕ onResume called 5009-5009/com.project.test D/TEST﹕ spinner item selected 5009-5009/com.project.test D/TEST﹕ spinner item selected 

I have 2 questions:

1) Why, when returning to it using the "Back" button, the counter counter registers 2 options for selecting items.

2) Is there a fix to prevent the appearance of two elements? Now the fragment is filled with duplicate data, since it extracts data twice.

** EDIT ** After changing to stateSpinner.setSelection(defaultState, false) , I would get a null Pointer exception in ballotsDisplay.removeAllViews(); it seems that ballotsDisplay is for some reason null with this change

stacktrace:

05-15 07: 25: 48.303 6153-6153 / com.poliseewriters.polisee E / AndroidRuntime: FATAL EXCEPTION: main java.lang.NullPointerException at com.polisee.ballotmeasures.BallotMeasuresFragment $ 1.onItemSelected (BallotMeasures28 .widget.AdapterView.fireOnSelected (AdapterView.java:882) in android.widget.AdapterView.selectionChanged (AdapterView.java:865) in android.widget.AdapterView.checkSelectionChanged (AdapterView.java:1017) in android.widget.Spinner. layout (Spinner.java{6363) at android.widget.AbsSpinner.setSelectionInt (AbsSpinner.java:292) on android.widget.AbsSpinner.setSelection (AbsSpinner.java:269) in com.polisee.ballotmeasures.BallotMeasuresFragment.setStateSragmentSsetMateStmentS .java: 314) in com.polisee.ballotmeasures.BallotMeasuresFragment.onCreateView (BallotMeasuresFragment.java:201) in the android.support.v4.app.Fragment.per file formCreateView (Fragment.java:1786) in the android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:953) file in android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1136) on android. support.v4.app.BackStackRecord.run (BackStackRecord.java:739) in android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:1499) at android.support.v4.app.FragmentManagerImpl $ 1.run (FragmentManager .java: 456) on android.os.Handler.handleCallback (Handler.java:605) on android.os.Handler.dispatchMessage (Handler.java:92) on android.os.Looper.loop (Looper.java:137) at android.app.ActivityThread.main (ActivityThread.java:4441) in java.lang.reflect.Method.invokeNative (native method) in java.lang.reflect.Method.invoke (Method.java UP11) at com.android .internal.os.ZygoteInit $ MethodAnd ArgsCaller.run (ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java∗51) in dalvik.system.NativeStart.main (native method)

** EDIT: Updated code to prevent onItemSelected from being executed twice, you need to add a null check for Display bulletins **

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (savedInstanceState != null) { Log.d("TEST", "bundle = " + savedInstanceState.toString()); } Log.d("TEST", "onCreateView called"); View view = (View) inflater.inflate(R.layout.fragment_ballot_measures, container, false); setStateSpinner(view); return view; } private void setStateSpinner(View view) { try { states = Utilities.getAllStateNames(); } catch (Exception e) { Log.e("Error", "Error retrieving names: " + e.getMessage()); } Spinner stateSpinner = (Spinner) view.findViewById(R.id.stateSpinner); final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.ballotmeasures_state_spinner, states); adapter.setDropDownViewResource(R.layout.ballotmeasures_state_spinner_dropdown); stateSpinner.setAdapter(adapter); stateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { // Callback method to invoke when a state has been selected public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { Log.d("TEST", "spinner item selected"); TextView stateSelected = (TextView) view; String stateSelectedStr = stateSelected.getText().toString(); // Remove all currently displayed views in the layout LinearLayout ballotsDisplay = (LinearLayout) getActivity().findViewById(R.id.ballotsDisplay); if (ballotsDisplay != null) { ballotsDisplay.removeAllViews(); } Map<String, String> calloutParams = new HashMap<String, String>(); calloutParams.put("state", stateSelectedStr); // AsyncTask to execute data retrieval new RetrieveBallots().execute(calloutParams); } public void onNothingSelected(AdapterView<?> parent) { return; } }); // Set default selection for spinner int defaultState = adapter.getPosition(userState); if (defaultState == -1) { defaultState = 0; } Log.d("TEST", "stateSpinner.setSelection"); stateSpinner.setSelection(defaultState, false); } 
+5
source share
2 answers

Use stateSpinner.setSelection(defaultState, false); instead of stateSpinner.setSelection(defaultState);

+7
source

The problem is that the onItemSelected() is called twice by the Android Framework (possibly by design), with the first parameter view null , and the second time it is created.

You cannot prevent the choice of two elements, but you can check if the view variable is null, if not, do the rest.

+4
source

All Articles