実行時に、FragmentManager
はユーザーの操作に応じて、フラグメントに対する追加、削除、置き換えなどのアクションを実行できます。commit するフラグメント変更の各セットは「トランザクション」と呼ばれます。トランザクション内で行う処理は、FragmentTransaction
クラスで提供される API を使用して指定できます。アクションが複数ある場合は、1 つのトランザクションにグループ化することができます。たとえば、1 つのトランザクションで複数のフラグメントの追加や置き換えを行えます。このグループ化は、(たとえばビューが分割されて)複数の兄弟フラグメントが 1 つの画面に表示されている場合に便利です。
各トランザクションをバックスタック(FragmentManager
によって管理される)に保存すると、ユーザーはフラグメントの変更を元に戻せるようになります。これは、アクティビティを逆方向に操作するのと同じです。
FragmentTransaction
のインスタンスを FragmentManager
から取得するには beginTransaction()
を呼び出します。次の例をご覧ください。
Kotlin
val fragmentManager = ... val fragmentTransaction = fragmentManager.beginTransaction()
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
各 FragmentTransaction
の最後の呼び出しでは、トランザクションを commit する必要があります。commit()
呼び出しでは、トランザクションにすべてのオペレーションが追加されたことが FragmentManager
に通知されます。
Kotlin
val fragmentManager = ... // The fragment-ktx module provides a commit block that automatically // calls beginTransaction and commit for you. fragmentManager.commit { // Add operations here }
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); // Add operations here fragmentTransaction.commit();
フラグメントの状態の変化の並べ替え
各 FragmentTransaction
で setReorderingAllowed(true)
を使用する必要があります。
Kotlin
supportFragmentManager.commit { ... setReorderingAllowed(true) }
Java
FragmentManager fragmentManager = ... fragmentManager.beginTransaction() ... .setReorderingAllowed(true) .commit();
動作の互換性を確保するため、並べ替えフラグはデフォルトで有効になっていません。
ただし、FragmentManager
が FragmentTransaction
を適切に実行できるようにする場合、特にバックスタック上で動作してアニメーションや遷移を実行する場合は、このフラグが必要です。このフラグを有効にすると、複数のトランザクションが同時に実行された場合、中間フラグメント(追加されてすぐに置き換えられるフラグメント)にライフサイクルの変更が行われず、アニメーションや遷移が実行されなくなります。このフラグは、トランザクションの最初の実行と、popBackStack()
によるトランザクションの逆方向の操作に影響することに注意してください。
フラグメントの追加と削除
FragmentManager
にフラグメントを追加するには、トランザクションで add()
を呼び出します。このメソッドは、フラグメントのコンテナの ID と、追加するフラグメントのクラス名を受け取ります。追加されたフラグメントは RESUMED
状態に移行します。コンテナはビュー階層の一部である FragmentContainerView
にすることを強くおすすめします。
ホストからフラグメントを削除するには、remove()
を呼び出し、findFragmentById()
または findFragmentByTag()
でフラグメント マネージャーから取得したフラグメント インスタンスを渡します。フラグメントのビューが以前にコンテナに追加されていた場合、この時点でビューはコンテナから削除されます。削除されたフラグメントは DESTROYED
状態に移行します。
コンテナの既存のフラグメントを、指定した新しいフラグメント クラスのインスタンスに置き換えるには、replace()
を使用します。replace()
の呼び出しは、コンテナ内のフラグメントで remove()
を呼び出し、同じコンテナに新しいフラグメントを追加することと同じです。
次のコード スニペットで、フラグメントを別のフラグメントに置き換える方法を示します。
Kotlin
// Create new fragment val fragmentManager = // ... // Create and commit a new transaction fragmentManager.commit { setReorderingAllowed(true) // Replace whatever is in the fragment_container view with this fragment replace<ExampleFragment>(R.id.fragment_container) }
Java
// Create new fragment and transaction FragmentManager fragmentManager = ... FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.setReorderingAllowed(true); // Replace whatever is in the fragment_container view with this fragment transaction.replace(R.id.fragment_container, ExampleFragment.class, null); // Commit the transaction transaction.commit();
この例では、R.id.fragment_container
で識別されるレイアウト コンテナ内にフラグメントが存在している場合、そのフラグメントを ExampleFragment
の新しいインスタンスに置き換えます。
デフォルトでは、FragmentTransaction
に行った変更はバックスタックに追加されません。これらの変更を保存するには、FragmentTransaction
で addToBackStack()
を呼び出します。詳しくは、フラグメント マネージャーをご覧ください。
commit の非同期性
commit()
を呼び出しても、トランザクションはすぐに実行されませんが、可能な限り早くメイン UI スレッドで実行されるようにスケジュールされます。ただし必要であれば、commitNow()
を呼び出して、UI スレッドでフラグメント トランザクションをすぐに実行できます。
commitNow
は addToBackStack
と互換性がありません。commit()
呼び出しで送信された保留中の FragmentTransactions
のうち、まだ実行されていないものをすべて実行するには、executePendingTransactions()
を呼び出します。このアプローチは、addToBackStack
と互換性があります。
ほとんどのユースケースでは、commit()
があれば十分です。
オペレーションの順序の重要性
FragmentTransaction
内でオペレーションを実行する順序は、setCustomAnimations()
を使用している場合には特に重要です。このメソッドは、指定されたアニメーションを、それに続くすべてのフラグメント オペレーションに適用します。
Kotlin
supportFragmentManager.commit { setCustomAnimations(enter1, exit1, popEnter1, popExit1) add<ExampleFragment>(R.id.container) // gets the first animations setCustomAnimations(enter2, exit2, popEnter2, popExit2) add<ExampleFragment>(R.id.container) // gets the second animations }
Java
getSupportFragmentManager().beginTransaction() .setCustomAnimations(enter1, exit1, popEnter1, popExit1) .add(R.id.container, ExampleFragment.class, null) // gets the first animations .setCustomAnimations(enter2, exit2, popEnter2, popExit2) .add(R.id.container, ExampleFragment.class, null) // gets the second animations .commit()
フラグメントのライフサイクルに対する制限
FragmentTransactions
は、トランザクションのスコープ内で追加された個々のフラグメントのライフサイクル状態に影響を与える可能性があります。FragmentTransaction
を作成するとき、setMaxLifecycle()
は指定されたフラグメントの最大の状態を設定します。たとえば、ViewPager2
は setMaxLifecycle()
を使用して、画面外のフラグメントを STARTED
状態に制限します。
フラグメントのビューの表示と非表示の切り替え
コンテナに追加されたフラグメントのビューの表示と非表示を切り替えるには、FragmentTransaction
メソッドの show()
と hide()
を使用します。
これらのメソッドは、フラグメントのライフサイクルに影響を与えずにフラグメントのビューの表示方法を設定します。
フラグメント内のビューの表示を切り替えるためにフラグメント トランザクションを使用する必要はありませんが、こうしたメソッドは、表示状態の変更をバックスタック上のトランザクションに関連付ける場合に便利です。
フラグメントのアタッチとデタッチ
FragmentTransaction
メソッド detach()
は UI からフラグメントをデタッチして、そのビュー階層を破棄します。フラグメントは、バックスタックに配置されたときと同じ状態(STOPPED
)を維持します。つまり、フラグメントは UI から削除されましたが、フラグメント マネージャーによってまだ管理されています。
attach()
メソッドは、以前にデタッチされたフラグメントを再アタッチします。これにより、ビュー階層が再作成され、UI にアタッチされて表示されます。
FragmentTransaction
は 1 つのアトミックな操作セットとして扱われるため、同じトランザクション内の同じフラグメント インスタンスで detach
と attach
の両方を呼び出すと、実質的に互いと相殺されます。これにより、フラグメントの UI が破棄されて即座に再作成されるのを回避できます。フラグメントをデタッチしてすぐに再アタッチするときに commit()
を使用している場合は、個別のトランザクションを executePendingOperations()
で区切って使用します。