web-dev-qa-db-de.com

Wie ersetze ich Fragment C durch Fragment A, wenn die Zurück-Taste gedrückt wird?

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?

34

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; -).

17
hcpl

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();
  }
}
29
user697495