2015-05-15 5 views
5

Ich erstellte einen Spinner für mein Fragment, die es mit Daten aus einem HTTP-Callout aufgefüllt. Wenn das Fragment zum ersten Mal erstellt wird, fülle ich das Auswahlfeld mit seinen Auswahlmöglichkeiten, setze seinen setOnItemSelectedListener und setze seine ursprüngliche Auswahl in onCreateView().Android Spinner's onItemSelected zweimal ausgeführt, wenn zurück zu Fragment

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); 

Wenn das Fragment erstellt wird, funktioniert alles gut, ist der Spinner Position auf seinen Standardsatz und der Spinner Artikel wird einmal ausgewählt, wie unten im Protokoll gezeigt:

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 

Das Problem tritt auf, wenn Ich navigiere vom Fragment zu einem anderen Fragment (ich speichere das Fragment auf Backstack). Wenn ich auf zurück zu meinem ursprünglichen Fragmente zurück zu gehen, scheint der Spinner seine Artikel zweimal ausgewählt zu haben:

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 

So habe ich 2 Fragen:

1) Warum funktioniert die Spinner-Register 2 Artikelauswahl Vorkommen wenn Sie von der Zurück-Taste zurückkehren.

2) Gibt es einen Fix, um zu verhindern, dass 2 Elementauswahlen auftreten? Momentan wird das Fragment mit doppelten Daten gefüllt, da es die Daten zweimal abruft.

** EDIT ** zu stateSpinner.setSelection(defaultState, false) Nach dem Wechsel, würde ich eine Null-Zeiger-Ausnahme bei ballotsDisplay.removeAllViews(); scheint wie ballotsDisplay mit dieser Änderung auf null aus irgendeinem Grund eingestellt ist

Stacktrace:

05 -15 07: 25: 48,303 6153-6153/com.poliseewriters.polisee E/Android Runtime: FATAL AUSNAHME: Haupt java.lang.NullPointerException bei com.polisee.ballotmeasures.BallotMeasuresFragment $ 1.onItemSelected (BallotMeasuresFragment.java:287) bei android.widget.AdapterView.fireOnSelected (AdapterView.java:882) bei android.widget.AdapterView.selectionChanged (AdapterView.java:865) bei android.widget.AdapterView.checkSelectionChanged (AdapterView.java:1017) bei android.widget.Spinner.layout (Spinner.java:363) bei android.widget.AbsSpinner.setSelectionInt (AbsSpinner.java:292) bei android.widget.AbsSpinner.setSelection (AbsSpinner.java:269) bei com. polisee.ballotmeasures.BallotMeasuresFragment.setStateSpinner (BallotMeasuresFragment.java:314) bei com.polisee.ballotmeasures.BallotMeasuresFragment.onCreateView (BallotMeasuresFragment.java:201) bei android.support.v4.app.Fragment.performCreateView (Fragment.java: 1786) bei android.s upport.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:953) bei android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1136) bei android.support.v4.app.BackStackRecord.run (BackStackRecord.java:739) bei android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:1499) bei android.support.v4.app.FragmentManagerImpl $ 1.run (FragmentManager.java:456) bei android .os.Handler.handleCallback (Handler.java:605) bei android.os.Handler.dispatchMessage (Handler.java:92) bei android.os.Looper.loop (Looper.java:137) bei android.app .ActivityThread.main (ActivityThread.java:4441) bei java.lang.reflect.Method.invokeNative (Native Methode) bei java.lang.reflect.Method.invoke (Methode.java:511) bei com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:784) bei com.android .internal.os.ZygoteInit.main (ZygoteInit.java:551) bei dalvik.system.NativeStart.main (native Methode)

** EDIT: Aktualisiert Code onItemSelected von der Ausführung zweimal zu verhindern, hinzuzufügen, benötigt null für ballotsDisplay überprüfen **

@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); 
} 

Antwort

7

Verwendung stateSpinner.setSelection(defaultState, false); anstelle von stateSpinner.setSelection(defaultState);

+0

Ich tat, was Sie gesagt haben, aber jetzt bekomme ich eine Nullpointer geworfen unter:. Linearlayout ballotsDisplay = (Linearlayout) getActivity() findViewById (R.id.ballotsDisplay); ballotsDisplay.removeAllViews(); Irgendeine Idee, warum dies jetzt passiert, nachdem Sie setSelection (..., false) verwendet haben? – user7702

+0

Bitte überprüfen Sie, ob ballotsDisplay richtig aufgeblasen wird. Scheint wie seine Null. – Manish

+0

Es tut. Wenn ich es zurück in stateSpinner.setSelection (Standard) umschalte, erhalte ich diese Nullzeigerausnahme nicht. Alles funktioniert gut, bis auf die doppelte Auswahl, wenn ich zurückschleiche. Ich blase das gesamte Layout auf (BallotsDisplay ist drin), bevor ich den Spinner einsetze. Nur wenn ich es in setSelection (default, false) ändere, tritt diese Ausnahme auf – user7702

4

Das Problem ist der onItemSelected() Rückruf zweimal durch Android-Framework aufgerufen wird (vielleicht durch Design), das erste Mal, wenn die view Parameter sind null, und das zweite Mal, es instanziiert wird.

Sie können nicht verhindern, dass 2 Elementauswahlen auftreten, aber Sie können überprüfen, ob die view Variable null ist, wenn nicht, tun Sie den Rest Dinge.

Verwandte Themen