5

Ich habe ein Activity mit drei Fragmente lässt sie A, rufen B und C. FragmentEin wird in der Aktivität onCreate() aufgerufen.Prevent The Same Fragment Mehr von Stapeln als einmal (addToBackStack)

FragmentA fragA = new FragmentA(); 
FragmentTransaction transaction = manager.beginTransaction(); 
transaction.add(R.id.activity2_layout, fragA, "A"); 
transaction.commit(); 

und wird mit Fragment B oder C ersetzt, wenn bestimmte Tasten gedrückt werden, und die FragmentTransaction ruft addToBackStack().

FragmentB fragB = new FragmentB(); //or C 
FragmentTransaction transaction = manager.beginTransaction(); 
transaction.replace(R.id.activity2_layout, fragB, "B"); //or C 
transaction.addToBackStack("B"); //or C 
transaction.commit(); 

Aber sagen wir mal ich FragmentB dreimal in einer Reihe nennen, wie kann ich es von Stapeln auf, um es selbst zu verhindern? Und zur gleichen Zeit möchte ich dies möglich: B genannt>C genannt>B genannt - aber wenn ich versuche ich will zurück B nur einmal geöffnet werden (C < B) anstelle von (B < C < B). Also im Grunde genommen den ersten backStack mit dem neuen entfernen.

Antwort

8

Von How to resume Fragment from BackStack if exists, die Ihrer Anfrage sehr ähnlich sind.

Es gibt eine Möglichkeit, den Backstack basierend auf dem Transaktionsnamen oder der ID, die von commit (z.mit dem Klassennamen des Fragments als Thijs bereits) erwähnt:

String backStateName = fragment.getClass().getName(); 

zu Backstack Hinzufügen:

FragmentTransaction ft = manager.beginTransaction(); 
ft.replace(R.id.content_frame, fragment); 
ft.addToBackStack(backStateName); 
ft.commit(); 

Wenn knallen:

getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

Also vor dem Fragment zu ersetzen, wir existance in überprüfen backstack like:

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0); 

if (!fragmentPopped){ //fragment not in back stack, create it. 
    ... 
    ... 
    ft.addToBackStack(backStateName); 
    ft.commit(); 
} 

Bitte überprüfen Sie die obige Frage und die akzeptierte Antwort für weitere Erklärungen.

+0

Dies ist die bessere Antwort, da es beide Fragen beantwortet :) –

1

Ich habe eine Ihrer Fragen, nämlich how can I prevent it from stacking on to it self?, in einem meiner eigenen Projekte vor einiger Zeit gelöst. Dies war der genaue Code, den ich dort verwendet:

public void setContent(@NonNull Fragment fragment, boolean addToBackStack) { 
    Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content); 
    if (current == null || !current.getClass().equals(fragment.getClass())) { 
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
     if (addToBackStack) { 
      transaction.addToBackStack(null).add(R.id.main_content, fragment).commit(); 
     } else { 
      transaction.replace(R.id.main_content, fragment).commit(); 
     } 
    } 
} 

Was dieser Code tut, ist überprüft von welcher Klasse die zur Zeit zeigt Fragment ist und vergleichen Sie das mit dem Fragment Sie es mit ersetzen möchten. Wenn sie gleich sind, tut es nichts. Dieser Code kann an Ihre Bedürfnisse anzupassen, wie so

Fragment newFragment = new FragmentB(); //OR FragmentC 
Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout); 
if (!current.getClass().equals(newFragment.getClass())) { 

    //POP BACKSTACK HERE LIKE EXPLAINED BELOW 

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
    final String tag = newFragment.getClass().getSimpleName(); 
    transaction.addToBackStack(tag); 
    transaction.add(R.id.activity2_layout, newFragment, tag); 
    transaction.commit(); 
} else { 
    //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME 
} 

Sicherzustellen, dass nur ein Fragment eines bestimmten Typs vorhanden ist, zu einer Zeit geformt werden wahrscheinlich durch knallen die Backstack bis vor dem ersten Auftreten des gleichen Fragments erreicht werden konnte . Ich habe keinen Code dafür geschrieben, aber es sollte nicht zu schwierig sein, dieses Feature zu implementieren. Wenn Sie es nicht selbst herausfinden können, lassen Sie es mich wissen und ich werde versuchen, Ihnen ein Beispiel zu schreiben :)

+0

Danke :) Nein, ein Beispiel wird nicht nötig sein :) Das einzige, was ich jetzt herausfinden muss, ist, wie man Backstacks entfernt, wenn es überhaupt möglich ist, da ich keine Dokumentation oder Beispiele finden kann Das. –

+1

Ich glaube nicht, dass das überhaupt möglich ist. Soweit ich weiß, hat der 'FragmentManager' genau einen Backstack. Sie können die Einträge deaktivieren und dann eine weitere hinzufügen, um die Anzahl der Einträge mit dem neuen Eintrag zu ersetzen. Solange Sie dies tun, bevor Sie 'commit()', sollten Sie in Ordnung sein :) –

+0

@IvanJavorovic von remove backStacks meinst du den Backstack zu löschen? –