37

私のシナリオ: アクティビティ 1 は、フラグメント A-> B-> C で構成されています。すべてのフラグメントは、次のコードを使用して追加されます。

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.content, fragment, TAG);
        ft.addToBackStack(TAG);
        ft.commit();

今、フラグメント C から、フラグメント A に直接戻りたいと思います。したがって、ft.addToBackStack(TAG)フラグメント C を追加しながらコメントしました。そのため、CI から [戻る] ボタンを押すと、画面に直接フラグメント A が表示されます。

ただし、フラグメント C は A に置き換えられません。実際、両方のフラグメントが表示されます。この問題を解決するにはどうすればよいですか?

4

3 に答える 3

30

2 つのことを行う必要があります - FragmentTransaction に A->B から名前を付けてから、Fragment C を使用しているときに、含まれているアクティビティで onBackPressed() をオーバーライドしてFragmentManager#popBackStack (文字列名、int フラグ)を呼び出します。例:

A->B からの遷移

getSupportFragmentManager()
  .beginTransaction()
  .replace(R.id.container, new FragmentB(), "FragmentB")
  .addToBackStack("A_B_TAG")
  .commit();

B->C からの遷移では、"FragmentC" をタグとして使用する同様のトランザクションが使用されます。

次に、含まれているアクティビティで 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();
  }
}
于 2013-02-05T18:18:53.807 に答える
20

仮説

戻りたいポイントをマークするにaddToBackStack(tag: String): FragmentTransactionは、 内の メソッドを使用します。このメソッドは、チェーン機能のみのインスタンスを返します。FragmentTransactionFragmentTransaction

popBackStackImmediate(tag: String, flag: int): voidその後、 のメソッドで戻りFragmentManagerます。タグは前に指定したものです。POP_BACK_STACK_INCLUSIVEフラグは、マークされたトランザクションを含む定数または のいずれか0です。

以下は、フラグメントが読み込まれるFrameLayoutwith idを持つ次のレイアウトの例です。content_frame

<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>

以下のコードは、レイアウト要素のコンテンツを id に置き換えるときに、フラグメント クラス名でフラグメントをマークしますcontent_frame

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

この例を完成させるために、タグをロードしたときにタグを使用して、まったく同じフラグメントに戻ることができるメソッドを作成します。

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

}

これを実際に実装するときは、フラグメント パラメータに null チェックを追加することをお勧めします ;-)。

于 2013-09-27T15:51:02.703 に答える