Ich verwende die Android-Kompatibilitätsbibliothek, um Fragmente zu implementieren, und habe das Layoutbeispiel so erweitert, dass ein Fragment eine Schaltfläche enthält, die ein anderes Fragment auslöst.
Im Auswahlbereich links habe ich 5 auswählbare Elemente - A B C D E
.
Jeder lädt ein Fragment (via FragmentTransaction:replace
) in das Detailfenster -a b c d e
Jetzt habe ich das Fragment e
um eine Schaltfläche erweitert , die ein weiteres Fragment e1
auch im Detailbereich lädt . Ich habe dies mit der e
onClick-Methode von fragment wie folgt gemacht:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
Wenn ich folgende Auswahl treffe:
E - e - e1 - D - E
Dann e
befindet sich das Fragment im Detailbereich. Das ist in Ordnung und was ich will. Wenn ich jedoch back
an dieser Stelle auf den Knopf drücke, geschieht nichts. Ich muss zweimal darauf klicken, weil e1
es noch auf dem Stapel ist. Außerdem habe ich nach dem Klicken eine Nullzeiger-Ausnahme in onCreateView erhalten:
Um dieses Problem zu lösen, habe ich bei jeder A B C D E
Auswahl Folgendes hinzugefügt :
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Sie fragen sich nur, ob dies die richtige Lösung ist oder ob ich etwas anderes tun sollte?
Die andere saubere Lösung, wenn Sie nicht alle Stapeleinträge einfügen möchten ...
Dadurch wird zuerst der Stapel bereinigt und dann ein neues Fragment geladen, sodass Sie zu jedem Zeitpunkt nur ein einzelnes Fragment im Stapel haben
quelle
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
vor a () zu ersetzen , da sind das Fragment calling LadenonCreateView()
,onActivityCreated()
etc. Wiederherstellen und verwüstet ein Fragment sofort schlecht. Das Fragment kann beispielsweise einen Empfänger registrieren. Dies wirkt sich auf die Leistung aus.FragmentTransaction
? Gibt es nur eine schlechte Leistung des falschen Fragmentstapels?Dank der Antwort von Joachim verwende ich den Code, um alle Backstack-Einträge endgültig zu löschen.
quelle
popBackStack(backStackId, INCLUSIVE)
Alle Fragmente (Status) werden wieder in backStackId eingefügt. Sobald Sie also die niedrigstei
, die Sie einfügen möchten, einfügen, sollten alle höheren gleichzeitig ausgeblendet werden. Was ist der Sinn einer Schleife?Ich habe viel nachgeforscht, um Backstack zu bereinigen, und sehe schließlich Transaction BackStack und seine Verwaltung . Hier ist die Lösung, die für mich am besten funktioniert hat.
Die obige Methode durchläuft alle Transaktionen im Backstack und entfernt sie sofort nacheinander.
Hinweis: Der obige Code funktioniert manchmal nicht und ich stehe wegen dieses Codes vor ANR. Bitte versuchen Sie dies nicht.
Update unten Methode entfernen alle Fregments dieses "Namens" aus dem Backstack.
quelle
Ich verwende einen ähnlichen Code wie diejenigen, die die while-Schleife verwenden, aber ich rufe die Anzahl der Einträge in jeder Schleife auf ... also nehme ich an, dass sie etwas langsamer ist
quelle
Wie in Wie man Fragmente aus dem Backstack und von LarsH hier schreibt , können wir mit dieser Methode mehrere Fragmente von oben nach unten in ein bestimmtes Tag ( zusammen mit dem markierten Fragment ) einfügen :
Ersetzen Sie "frag" durch das Tag Ihres Fragments. Denken Sie daran, dass wir zuerst das Fragment zum Backstack hinzufügen sollten mit:
Wenn wir Fragmente mit hinzufügen, werden Fragmente
addToBackStack(null)
nicht auf diese Weise eingeblendet.quelle
quelle