【Kotlin/Android】Fragment間を画面遷移する方法!FragmentManagerとpopBackStack

この記事からわかること
- Android Studio/KotlinでFragmentを画面遷移する方法
- parentFragmentManagerの使い方
- popBackStackの注意点
- バックスタックとは?
index
[open]
\ アプリをリリースしました /
- Android Studio:Flamingo
- Kotlin:1.8.20
この記事ではFragment間を移動するために使用するparentFragmentManager
などの使用方法を紹介していきます。実際にFragmentを作成して実装する流れは上記の記事で紹介しているので実装の流れを知りたい方は参考にしてください。
FragmentManagerとは?
FragmentManager
はFragmentの追加や削除、置換などをコントロールするためのクラスです。このクラスを活用することでFragmentで構成されたViewの画面遷移を実装することが可能になります。
またFragmentManager
はバックスタック機能を持っています。これはトランザクションを管理する際に使用される概念であり、簡単にいうと画面遷移の履歴を保持しておき、「戻る」ボタンなどで前の状態に戻る機能を実現するためのものになります。
FragmentManager
は自身でインスタンス化するのではなくActivity
やFragment
のメソッド(Kotlinではプロパティとして参照可能)を介してアクセスすることができるようになっています。
Activity:getSupportFragmentManager()
this.supportFragmentManager
Fragment:getParentFragmentManager()/getChildFragmentManager()
Fragmentの場合は親と子の両方のFragmentManager
を取得することが可能です。
this.parentFragmentManager
this.childFragmentManager
階層構造で見ると以下のような感じになっているようです。

ちなみに画面遷移を実装する方法としてNavigation Component
などがありますが、こちらも内部的にFragmentManager
を使用して実装されているようです。
Fragmentを遷移する方法
FragmentManager
で画面を遷移(Fragmentの追加や削除、置換など)を行う方法をまとめていきます。まずは前提としてレイアウトファイルにFragmentを表示させるためのFragmentContainerView
を追加するのを忘れないようにしてください。
<androidx.fragment.app.FragmentContainerView
android:id="@+id/main_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:elevation="10dp"/>
FragmentManager
でFragmentを操作するにはbeginTransaction
メソッドを実行して最初にトランザクションを作成します。生成したトランザクションに対してFragmentの追加や置換をなどを行い、その変更を最後にコミットすることで処理が実行されます。
val fragmentManager = supportFragmentManager
// トランザクション取得
val transaction = fragmentManager.beginTransaction()
// トランザクション内の処理を実装
// 〜〜〜〜
// トランザクションをコミット
transaction.commit()
apply
を使用することでもっとコンパクトに記述することも可能です。
supportFragmentManager.beginTransaction().apply {
// トランザクション内の処理を実装
// 最後にはコミットする
commit()
}
Fragmentを追加する
Fragmentを追加するにはトランザクションの中でadd
メソッドを使用します。引数には対象のレイアウトと表示したいFragmentインスタンスを渡します。
supportFragmentManager.beginTransaction().apply {
add(R.id.main_frame, FirstFragment())
addToBackStack(null)
commit()
}
Fragmentを入れ替える
Fragmentを入れ替えるにはトランザクションの中でreplace
メソッドを使用します。引数には対象のレイアウトと表示したいFragmentインスタンスを渡します。
supportFragmentManager.beginTransaction().apply {
replace(R.id.main_frame, FirstFragment())
addToBackStack(null)
commit()
}
Fragmentを削除する
Fragmentを削除するにはトランザクションの中でremove
メソッドを使用します。
parentFragmentManager.beginTransaction().remove(this).commit()
画面を戻る処理はこのremove
メソッドもしくは後述するpopBackStack
メソッドを実行します。
バックスタックの管理・操作
FragmentManager
でバックスタックを管理・操作する方法をまとめていきます。バックスタック機能はトランザクションを管理する概念でした。トランザクション単位で履歴として保持され、戻るボタンを押下した時などは逆順にトランザクションが実行されることで前の状態に戻ることができます。
トランザクションをバックスタックに追加する
トランザクションをバックスタックに追加にはaddToBackStack
メソッドを実行します。引数には必要であればトランザクションの識別子を文字列を渡すことができます。
supportFragmentManager.beginTransaction().apply {
add(R.id.main_frame, FirstFragment())
addToBackStack(null) // バックスタックに保存する
commit()
}
トランザクションを戻す
トランザクションを戻す(画面を戻すなど)処理を行うにはpopBackStack
メソッドを使用します。
parentFragmentManager.popBackStack()
複数画面戻りたい場合はその回数だけpopBackStack
メソッドを呼び出せばOKです。
parentFragmentManager.apply {
popBackStack()
popBackStack()
}
addToBackStack
メソッドで識別子を指定している場合はその識別子を渡すことでそのトランザクションまで戻ることが可能です。フラグにはポップ操作の挙動を制御するためのフラグを渡しますが基本的に0で問題ありません。
parentFragmentManager.apply {
popBackStack("ActivityToFragment", 0)
}
popBackStackの注意点
popBackStack
で戻った場合はFragmentのインスタンスは破棄されないようです。表示しているFragmentが不要になり、戻りたい場合はremove
を使用することでインスタンスを破棄することが可能です。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。