wake-up-neo.com

Löschen Sie den Stapel mit Fragmenten

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? 

215
biquillo

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

373
PJL

Um eine Antwort auf @ Warpzits Kommentar zu geben und anderen das Auffinden zu erleichtern.

Benutzen:

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
132

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();
}
37
dbm

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();
}
17
belphegor

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);
16
Md Mohsin

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)
13
georgehardcore

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.

8
Nicks

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(); }
3
trans

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();
    }
}
2
Arhat Baid

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();
        }
    }
2
Alok Singh

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();
            }
        }
    });
}
1
saulobrito
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;
}
0
user3509903
    private void clearBackStack(){
        SupportFragmentManaer fm = getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

Ein Aufruf an diese Methode wäre sehr ordentlich.

  1. Keine Schleife erforderlich.
  2. Wenn Sie Animationen in Fragmenten verwenden, werden nicht zu viele Animationen angezeigt. Aber mit Hilfe der Schleife wird.
0
Wajid Ali

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);
    }
}
0
Chenxi