Mein Szenario: Aktivität 1 besteht aus Fragmenten A-> B-> C. Alle Fragmente werden mit diesem Code hinzugefügt:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content, fragment, TAG);
ft.addToBackStack(TAG);
ft.commit();
Nun möchte ich von Fragment C direkt zu Fragment A zurückkehren. Daher habe ich ft.addToBackStack(TAG)
kommentiert, während ich Fragment C hinzufüge. Wenn ich also die Zurück-Taste von C drücke, wird Fragment A direkt auf dem Bildschirm angezeigt.
Fragment C wird jedoch nicht durch A ersetzt. Tatsächlich sind beide Fragmente sichtbar. Wie löse ich dieses Problem?
Theorie
Verwenden Sie die addToBackStack(tag:String):FragmentTransaction
-Methode innerhalb von FragmentTransaction
, um einen Punkt zu markieren, zu dem Sie zurückkehren möchten. Diese Methode gibt die Instanz FragmentTransaction
nur für die Kettenfähigkeit zurück.
Dann kehren Sie mit der popBackStackImmediate(tag:String,flag:int):void
-Methode aus dem FragmentManager
zurück. Das Tag ist das, was Sie zuvor angegeben haben. Das Flag ist entweder die Konstante POP_BACK_STACK_INCLUSIVE
, Die die markierte Transaktion enthält, oder 0
.
Beispiel
Was folgt, ist ein Beispiel mit dem folgenden Layout mit einem FrameLayout
mit der ID content_frame
, In das die Fragmente geladen werden.
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
Android:id="@+id/textView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@string/hello_world" />
<FrameLayout
Android:id="@+id/content_frame"
Android:layout_below="@id/textView"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</RelativeLayout>
Der folgende Code markiert ein Fragment anhand seines Fragmentklassennamens, wenn der Inhalt des Layoutelements durch die ID content_frame
Ersetzt wird.
public void loadFragment(final Fragment fragment) {
// create a transaction for transition here
final FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
// put the fragment in place
transaction.replace(R.id.content_frame, fragment);
// this is the part that will cause a fragment to be added to backstack,
// this way we can return to it at any time using this tag
transaction.addToBackStack(fragment.getClass().getName());
transaction.commit();
}
Und um dieses Beispiel zu vervollständigen, eine Methode, mit der Sie mithilfe des Tags zum exakt gleichen Fragment zurückkehren können, wenn Sie es geladen haben.
public void backToFragment(final Fragment fragment) {
// go back to something that was added to the backstack
getSupportFragmentManager().popBackStackImmediate(
fragment.getClass().getName(), 0);
// use 0 or the below constant as flag parameter
// FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
Wenn Sie dies für real implementieren, sollten Sie den fragment-Parameter mit einem Null-Häkchen versehen; -).
Sie müssen zwei Dinge tun - benennen Sie die FragmentTransaction von A-> B und überschreiben Sie dann onBackPressed () in Ihrer enthaltenen Aktivität, um FragmentManager # popBackStack (String name, int flags) aufzurufen, wenn Sie sich auf Fragment C befinden Beispiel:
Übergang von A-> B
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, new FragmentB(), "FragmentB")
.addToBackStack("A_B_TAG")
.commit();
Beim Übergang von B-> C wird eine ähnliche Transaktion mit "FragmentC" als Tag verwendet.
Dann überschreiben Sie in Ihrer enthaltenden Aktivität onBackPressed ():
@Override
public void onBackPressed() {
if (getSupportFragmentManager().findFragmentByTag("FragmentC") != null) {
// I'm viewing Fragment C
getSupportFragmentManager().popBackStack("A_B_TAG",
FragmentManager.POP_BACK_STACK_INCLUSIVE);
} else {
super.onBackPressed();
}
}