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);
}
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
Bitte überprüfen Sie, ob ballotsDisplay richtig aufgeblasen wird. Scheint wie seine Null. – Manish
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