2013-12-19 8 views
8

Ich bin ziemlich neu in Android-Entwicklung und jetzt in seltsames Verhalten läuft.FragmentTransaction: ersetzen und addToBackStack nicht zusammenarbeiten?

  • Ich habe ein leeres FrameLayout, um den Container eines Fragments zu sein.
  • Wenn der Benutzer zum ersten Mal eine Taste drückt, erzeuge ein neues Fragment und lege den Behälter hinein.
  • Wenn der Benutzer später eine Taste drückt und ein Fragment im Container vorhanden ist, ersetzen Sie den vorhandenen durch einen neu erzeugten.
  • Wenn der Benutzer die Zurück-Taste drückt, entfernen Sie das Fragment im Container.

Hier ist mein Code

public void showFragment(View v) { 
    FragmentA f = new FragmentA(); 

    FragmentManager fm = getSupportFragmentManager(); 
    String tag = f.getFragmentTag(); // instance method of a to get a tag 

    FragmentTransaction ft = fm.beginTransaction(); 
    ft.setCustomAnimations(R.anim.slide_in_top, 0, 0, R.anim.slide_out_top);    
    ft.replace(R.id.container, f, tag); 
    ft.addToBackStack(tag); 
    ft.commit(); 
} 

@Override 
public void onBackPressed() { 
    FragmentManager fm = getSupportFragmentManager(); 
    if (fm.getBackStackEntryCount() > 0) { 
     fm.popBackStack(); 
    } else { 
     super.onBackPressed(); 
    } 
} 

Wenn der Benutzer drücken Sie die Taste zum ersten Mal, verhält es wie das, was ich erwartet hatte, neue Fragment zu Container hinzufügen. Aber wenn der Benutzer das zweite Mal die Taste drückt, während der Behälter noch ein Fragment enthält, wird anstelle eines Ersatzes ein neues hinzugefügt. Also, 2 Fragmente im Container, 2 zurück drücken, um alle Fragmente zu entfernen.

Ich fand, dass, wenn ich die Zeile entfernen

ft.addToBackStack(); 

und Nacharbeit der onBackPress() -Methode wie folgt, es funktioniert wieder wie ich (zu einem Zeitpunkt 1 Fragment in Behälter) erwartet

grundsätzlich manuell entfernen Fragment statt popFromBackStack Methode

private FragmentA currentFragment = null; // to hold the reference to exising fragment, if any. 

@Override 
public void onBackPressed() { 
    if (currentFragment != null) { 
     FragmentManager fm = getSupportFragmentManager(); 
     FragmentTransaction ft = fm.beginTransaction(); 
     ft.setCustomAnimations(0, R.anim.slide_out_top); 
     ft.remove(currentFragment); 
     ft.commit(); 

     currentFragment = null; 
    } else { 
     super.onBackPressed(); 
    } 
} 

Also, meine questio n sind

  • Ersetzen und AddToBackStack funktioniert nicht zusammen?
  • oder habe ich etwas falsch gemacht?

Schätzen Sie alle Kommentare und Vorschläge.

+0

Ich denke, dies ist der Grund: „Wenn Sie rufen addToBackStack nicht(), wenn Sie eine Transaktion ausführen, die ein Fragment entfernt, dann ist das Fragment zerstört wird, wenn die Transaktion festgeschrieben wird Wenn Sie beim Entfernen eines Fragments addToBackStack() aufrufen, wird das Fragment gestoppt und fortgesetzt, wenn der Benutzer zurück navigiert. " Wenn Sie addToBackStack() verwenden, werden vorherige Fragmente gestoppt und beibehalten. Siehe: https://developer.android.com/guide/components/fragments.html#Transactions –

Antwort

13

addToBackstack erstellt eine Momentaufnahme des Status Ihrer Fragmente. Das heißt, wenn Sie die Zurück-Taste drücken, kehren Sie tatsächlich zum letzten Zustand zurück, in dem addToBackstack aufgerufen wurde.

In Ihrem Fall fügen Sie ein Fragment hinzu. Der Zurück-Knopf würde dieses hinzugefügte Fragment entfernen. Wenn Sie replace aufrufen und erneut zum Backstack hinzufügen, haben Sie jetzt zwei Zustände auf dem Backstack (1. wenn Sie das erste Fragment hinzugefügt hatten, 2. wenn Sie keine Fragmente hinzugefügt hatten). Wenn Sie die Zurück-Schaltfläche verwenden, um das aktuelle Fragment zu entfernen, verwenden Sie nicht addToBackstack. Verwenden Sie nur addToBackstack, wenn Sie den Status von Fragmenten in einer Ansicht beibehalten möchten.

+0

Hallo Spidy, vielen Dank für Ihren Kommentar. Ich bin immer noch ziemlich verwirrend, aber kann ich sagen, in meinem Fall sollte ich addToBackStack nicht verwenden? –

+1

Ja, es klingt wie Sie für Ihren Anwendungsfall – Spidy

+3

@Spidy auf der Android-Entwicklerwebsite nicht addToBackstack brauchen https://developer.android.com/training/implementing-navigation/temporal.html#back-fragments sie sagen, dass Sie sollten addToBackStack verwenden, um beim Navigieren zwischen Fragmenten die richtige Navigation nach hinten bereitzustellen. Was sind deine Argumente, sie nicht zu benutzen? und 2: „In Ihrem Fall fügen Sie ein Fragment der Zurück-Taste entfernen würde dieses Fragment hinzugefügt Wenn Sie ersetzen rufen, und fügen Sie wieder Backstack, Sie haben jetzt zwei Staaten auf dem Backstack..“. Wo in seinem Code fügt er ein Fragment hinzu? Ich sehe nur ersetzen() – Rule

-2

Für diejenigen, die noch nach einer Lösung suchen.

In der Hauptklasse Activity (die die Fragmente hostet) überschreiben Sie einfach onBackPressed().

@Override 
public void onBackPressed() { 
    if (getFragmentManager().getBackStackEntryCount() > 0){ 
     getFragmentManager().popBackStack(); 
    } else { 
     super.onBackPressed(); 
    } 
} 

Es gibt keine onBackPressed() Methode Fragment, und dieses Verfahren ist nur für die activity.Wenn wir also die Zurück-Taste drücken, wird das Standardverhalten von activity gezeigt, was

ist

werden Sie entweder zur vorherige Tätigkeit gehen (wenn vorhanden) oder die App beendet.

Jetzt müssen wir diese Methode außer Kraft zu setzen, die activity zu sagen, dass, wenn wir die Zurück-Taste drücken, wenn es irgendwelche Fragmente im Rücken Stapel sind, knallen sie aus (und das ist, wenn die addToBackStack() kommt ins Bild). Ansonsten folgen Sie dem Standardverhalten.

Mehr Details finden Sie hier here

Verwandte Themen