Ich habe meine Android-App auf Waben portiert und einen großen Refactor erstellt, um Fragmente zu verwenden. In meiner vorherigen Version habe ich beim Drücken der Home-Taste einen ACTIVITY_CLEAR_TOP
ausgeführt, um den hinteren Stapel zurückzusetzen.
Jetzt ist meine App nur eine einzige Aktivität mit mehreren Fragmenten. Wenn ich also die Home-Taste drücke, ersetze ich einfach eines der Fragmente darin. Wie kann ich meinen Backstack löschen, ohne startActivity
mit dem ACTIVITY_CLEAR_TOP
-Flag verwenden zu müssen?
Ich habe hier etwas Ähnliches gepostet
Aus Joachim's Antwort, aus Dianne Hackborn:
http://groups.google.com/group/Android-developers/browse_thread/thread/d2a5c203dad6ec42
Ich endete nur mit:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Könnte aber auch so etwas wie verwendet haben:
FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)
Dadurch werden alle Staaten bis zu dem genannten angezeigt. Sie können das Fragment dann einfach durch das ersetzen, was Sie möchten
Um eine Antwort auf @ Warpzits Kommentar zu geben und anderen das Auffinden zu erleichtern.
Benutzen:
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Bei allem Respekt gegenüber allen Beteiligten; Ich bin sehr überrascht zu sehen, wie viele von Ihnen den gesamten Fragment-Backstack mit einem einfachen löschen konnten
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Laut Android-Dokumentation (bezüglich des Arguments name
- das "Null" in den beanspruchten Arbeitsvorschlägen).
Bei null wird nur der oberste Status angezeigt
Jetzt ist mir klar, dass ich keine Kenntnisse über Ihre speziellen Implementierungen habe (z. B. wie viele Einträge Sie zum gegebenen Zeitpunkt auf dem Backstack haben), aber ich würde mein ganzes Geld auf die akzeptierte Antwort setzen, wenn ich eine genau definierte erwarte Verhalten über eine größere Bandbreite von Geräten und Anbietern:
(als Referenz etwas zusammen mit diesem)
FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();'
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
fm.popBackStack();
}
Die akzeptierte Antwort reichte mir nicht. Ich musste verwenden:
FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
fm.popBackStackImmediate();
}
Funktioniert für mich und einfacher Weg ohne Loop:
FragmentManager fragmentManager = getSupportFragmentManager();
//this will clear the back stack and displays no animation on the screen
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Klarer Backstack ohne Schlaufen
String name = getSupportFragmentManager().getBackStackEntryAt(0).getName();
getSupportFragmentManager().popBackStack(name, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Wobei name der Parameter addToBackStack () ist
getSupportFragmentManager().beginTransaction().
.replace(R.id.container, fragments.get(titleCode))
.addToBackStack(name)
Ich wollte nur hinzufügen: -
Mit folgendem aus dem Backstack springen
fragmentManager.popBackStack ()
es geht nur darum, die Fragmente aus der Transaktion zu entfernen, und zwar auf keine Weise, um das Fragment vom Bildschirm zu entfernen .. Im Idealfall ist es möglicherweise für Sie nicht sichtbar, aber es können zwei oder drei Fragmente übereinander angeordnet sein Beim Drücken der Rücktaste kann die Benutzeroberfläche unübersichtlich und gestapelt aussehen.
Nehmen wir nur ein einfaches Beispiel: -
Angenommen, Sie haben ein FragmentA, das Fragmnet B mit fragmentmanager.replace () lädt, und dann addToBackStack, um diese Transaktion zu speichern. __ Der Fluss ist also: -
SCHRITT 1 -> FragmentA-> FragmentB (wir sind zu FragmentB gewechselt, Fragment A ist jedoch im Hintergrund und nicht sichtbar).
Jetzt erledigen Sie einige Arbeiten in fragmentB und klicken auf die Schaltfläche Speichern.
SCHRITT 2-> Beim Speichern von FragmentB kehren wir zu FragmentA zurück.
SCHRITT 3 -> Ein häufiger Fehler wäre also ... in Fragment B führen wir fragment Manager.replace () fragmentB mit fragmentA aus.
Aber was wirklich passiert, laden wir Fragment A erneut und ersetzen Fragment B. Nun gibt es zwei FragmentA (eines von STEP-1 und eines von diesem STEP-3).
Zwei Instanzen von FragmentsA sind übereinander gestapelt, was möglicherweise nicht sichtbar ist, jedoch vorhanden ist.
Selbst wenn der Backstack mit den oben genannten Methoden gelöscht wird, wird die Transaktion jedoch gelöscht, nicht jedoch die tatsächlichen Fragmente .. _ Wenn Sie also in einem solchen Fall idealerweise auf einen Druck auf die Schaltfläche "Speichern" klicken, müssen Sie einfach zu fragmentA zurückkehren.fm.popBackStack () oder fm.popBackImmediate ().
Gehen Sie also zu Schritt3 -> fm.popBackStack () zurück zu fragmentA, das sich bereits im Speicher befindet.
Wenn Sie die documentation lesen und untersuchen, was die Fragment-ID ist, scheint es sich einfach um den Stack-Index zu handeln.
fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Null (0
) ist der unterste Stapel des Stapels. Wenn Sie also den Stapel aufklappen, wird der Stapel gelöscht.
CAVEAT: Obwohl das Obige in meinem Programm funktioniert, zögere ich ein wenig, da die FragmentManager-Dokumentation niemals angibt, dass die ID der Stack-Index ist. Es macht Sinn, dass es sein würde, und alle meine Debug-Protokolle haben gezeigt, dass es das ist, aber vielleicht unter bestimmten Umständen nicht? Kann jemand dies auf die eine oder andere Weise bestätigen? Wenn dies der Fall ist, ist das Obige die beste Lösung. Wenn nicht, ist dies die Alternative:
while(fragmentManager.getBackStackEntryCount() > 0) { fragmentManager.popBackStackImmediate(); }
Verwenden Sie einfach diese Methode und übergeben Sie das Context & Fragment-Tag, bis zu dem Sie die Backstake-Fragmente entfernen müssen.
Verwendungszweck
clearFragmentByTag(context, FragmentName.class.getName());
public static void clearFragmentByTag(Context context, String tag) {
try {
FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();
for (int i = fm.getBackStackEntryCount() - 1; i >= 0; i--) {
String backEntry = fm.getBackStackEntryAt(i).getName();
if (backEntry.equals(tag)) {
break;
} else {
fm.popBackStack();
}
}
} catch (Exception e) {
System.out.print("!====Popbackstack error : " + e);
e.printStackTrace();
}
}
Es funktioniert für mich, probiere es aus:
public void clearFragmentBackStack() {
FragmentManager fm = getSupportFragmentManager();
for (int i = 0; i < fm.getBackStackEntryCount() - 1; i++) {
fm.popBackStack();
}
}
Ich habe diese Arbeit so gemacht:
public void showHome() {
getHandler().post(new Runnable() {
@Override
public void run() {
final FragmentManager fm = getSupportFragmentManager();
while (fm.getBackStackEntryCount() > 0) {
fm.popBackStackImmediate();
}
}
});
}
private boolean removeFragFromBackStack() {
try {
FragmentManager manager = getSupportFragmentManager();
List<Fragment> fragsList = manager.getFragments();
if (fragsList.size() == 0) {
return true;
}
manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private void clearBackStack(){
SupportFragmentManaer fm = getSupportFragmentManager();
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
Ein Aufruf an diese Methode wäre sehr ordentlich.
Hallo ~ Ich habe eine Lösung gefunden, die viel besser ist: https://Gist.github.com/ikew0ng/8297033
/**
* Remove all entries from the backStack of this fragmentManager.
*
* @param fragmentManager the fragmentManager to clear.
*/
private void clearBackStack(FragmentManager fragmentManager) {
if (fragmentManager.getBackStackEntryCount() > 0) {
FragmentManager.BackStackEntry entry = fragmentManager.getBackStackEntryAt(0);
fragmentManager.popBackStack(entry.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}