2013-04-08 6 views
5

Gegeben die Anwendungsfluss in der Grafik zeigen und im folgenden Text beschrieben.Fragment, das im Backstack nicht am höchsten ist, wird wieder aufgenommen

Application flow

  1. Fragment 1 ist das niedrigste Fragment, aber nicht in der Backstack durch disallowAddToBackStack Einstellung.
  2. Fragment 2 wird unter Verwendung von fragmentTransaction.addToBackStack() auf den Stapel geschoben.
  3. Eine neue Instanz von Fragment 1 wird auf den Stapel geschoben.
  4. Das oberste Fragment (Fragment 1) wird aus dem Stapel entnommen.
  5. Aktivität 2 wird Vordergrund.
  6. Aktivität 1 wird Vordergrund.

Hier ist die verallgemeinerte Methode I verwenden Fragmente zu handhaben:

private void changeContainerViewTo(int containerViewId, Fragment fragment, 
            Activity activity, String backStackTag) { 

    if (fragmentIsAlreadyPresent(containerViewId, fragment, activity)) { return; } 
    final FragmentTransaction fragmentTransaction = 
       activity.getFragmentManager().beginTransaction(); 
    fragmentTransaction.replace(containerViewId, fragment); 
    fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    if (backStackTag == null) { 
     fragmentTransaction.disallowAddToBackStack(); 
    } else { 
     fragmentTransaction.addToBackStack(backStackTag); 
    } 
    fragmentTransaction.commit(); 
} 

Problem

Wenn Aktivität 1 wieder aufgenommen in der letzten Stufe die niedrigste Instanz von Fragment 1 auch wieder aufnimmt. Zu diesem Zeitpunkt gibt Fragment 1 null an getActivity() zurück.

Frage

  • Warum ein Fragment ist, das wieder nicht die oberste auf dem Stapel ist?
  • Wenn die Fortsetzung des Fragments korrekt ist - wie soll ich ein losgelöstes Fragment behandeln?
+0

Sind das erste Fragment1 und das Fragment2 dieselbe Containeransicht und welche Transaktion verwenden Sie im zweiten Schritt? – Evos

+0

Ja, Fragment1 und Fragment2 verwenden dieselbe Containeransicht. – JJD

+0

Und was ist mit Transaktionstyp: "ersetzen", "hinzufügen"? – Evos

Antwort

1

Ich sehe nicht, wie das passieren würde, es sei denn, (je nachdem, wie Sie die Schritte beschrieben) Sie haben verstanden, wie fragmentTransaction.addToBackStack() funktioniert: es schafft, welche Transaktionen in Backstack gestellt werden, nicht Fragmente.

aus der Android-Dokumentation:

von addToBackStack() aufgerufen, die ersetzen Transaktion an die gespeichert stapeln zurück, so kann der Benutzer die Transaktion rückgängig machen und das vorherige Fragment zurückbringen, indem Sie die Zurück-Taste drücken .

Also, wenn Ihr Schritt 2 sieht so etwas wie dies in Code:

fragmentTransaction.replace(containerViewId, fragment2); 
fragmentTransaction.addToBackStack(); 
fragmentTransaction.commit(); 

und Ihren Schritt 3:

fragmentTransaction.disallowAddToBackStack()//or just no call to addToBackStack - you do not say 
fragmentTransaction.replace(containerViewId, newfragment1); 
fragmentTransaction.commit(); 

An diesem Punkt wird Fragment2 aus dem Backstack entfernt werden, und Dein Backstack besteht aus den beiden Fragment1-Instanzen. In Schritt 4 öffnest du den obersten, was bedeutet, dass du das unterste Fragment1 jetzt oben haben solltest.

Dies erklärt, warum es das wiederaufgenommene Fragment ist, wenn Sie zu der Aktivität zurückkehren. Aber ich fürchte nicht, warum es scheinbar von seiner Aktivität losgelöst ist.

+0

Ich habe festgestellt, dass Sie '.disallowAddToBackStack()' vor '.replace()' aufrufen. Siehe meine aktualisierte Frage. Könnte das ein Problem sein? – JJD

+1

nein, die Reihenfolge spielt keine Rolle. Es sind nur Attribute, die Sie beim Erstellen Ihrer Transaktion festlegen. Sie werden nicht verwendet, bis Sie schließlich die Festschreibung aufrufen. – salfon

+0

wenn Sie noch so etwas wie schritt1 tun) 'changeContainerViewTo (containerId, afragment1, Aktivität, null)' step2) 'changeContainerViewTo (containerId, afragment2, Aktivität, tag)' step3) 'changeContainerViewTo (containerId, afragment1, Aktivität , null) ' das ist wahrscheinlich nicht das, was Sie wollen - versuchen, Null für Step2's Tag-Parameter und einen Nicht-Null-Wert für Step3's Tag-Parameter übergeben. Kurz gesagt, Sie möchten nur addToBackStack aufrufen, wenn das Fragment, das in einer Transaktion ersetzt wird, das ist, was Sie im Backhistory speichern möchten. – salfon

2

Wenn eine Activity Benutzeroberfläche nicht anzeigt und dann zur UI-Anzeige kommt, ist die zugehörige FragmentManager mit all Ihren Fragmenten im Sterben und Sie müssen ihren Status wiederherstellen.

Als documentation sagt:

Es gibt viele Situationen, in denen ein Fragment kann meist abgerissen werden (wie zum Beispiel, wenn ohne UI zeigt auf der Rückseite Stapel gelegt), aber sein Zustand wird erst gespeichert werden seine besitzende Tätigkeit muss tatsächlich seinen Staat retten.

In Ihrem ActivityonSaveInstanceState und onRestoreInstanceState, versuchen Sie sparen Fragment Referenzen und sie dann mit so etwas wie diese wieder her:

public void onSaveInstanceState(Bundle outState){ 
    getFragmentManager().putFragment(outState,"myfragment", myfragment); 
} 
public void onRetoreInstanceState(Bundle inState){ 
    myFragment = getFragmentManager().getFragment(inState, "myfragment"); 
} 

diese ausprobieren und haben Glück! :-)

1

Android OS kann und wird Fragmente erstellen und zerstören, wenn es für richtig hält. Dies tritt wahrscheinlich auf, wenn Sie Aktivität 2 starten und zu Aktivität 1 zurückkehren. Ich würde sicherstellen, dass es sich nicht um das aktiv angezeigte Fragment handelt. Was wahrscheinlich geschieht, ist, dass Sie einige der Erstellungsschritte für Fragment 1 ausführen, bevor es die Erstellungsschritte für Fragment 2 ausführt.

Für die Handhabung der gelösten Fragmente sollten Sie einen Blick auf diese page werfen. Der Kern davon ist, dass Sie die getActivity nur in bestimmten Fragmentfunktionen verwenden sollten (basierend auf der fragment life cycle). Dies kann bedeuten, dass Sie einen Teil Ihrer Logik in andere Funktionen verschieben müssen.

Verwandte Themen