今回はFragmentManagerについて調べたことをまとめようと思います
FragmentManagerをどのインタンスから作成するかを意識しないとうまく表示できなかったりと想定外なことが起こるので注意が必要です (今回は指定違いで想定外なことが起こっていました)
FragmentManagerとは?
FragmentManager
は、アプリのFragmentに対する追加、削除、置換、バックスタックへの追加などを実行するためのクラスです
FragmentManagerは生成されたFragmentのインスタンスの状況を管理して、再度呼ばれると復元してくれます
FragmentManagerがTransaction
を使うことで、フラグメントに対する追加などのアクションを実行します
Transactionはいくつかの命令をまとめて処理するときに使われるものです。命令のうちどれかに不都合があると、処理自体が停止されます
主に使用するアクションは次のような実装です
// 追加 val testFragment = FirstFragment() val fragmentTransaction = supportFragmentManager.beginTransaction() fragmentTransaction.add(R.id.fragment_container, testFragment) fragmentTransaction.commit() // 置換 val testFragment = FirstFragment() val fragmentTransaction = supportFragmentManager.beginTransaction() fragmentTransaction.replace(R.id.fragment_container, testFragment) fragmentTransaction.commit() // 削除 val fragmentTransaction = supportFragmentManager.beginTransaction() fragmentTransaction.remove(testFragment) fragmentTransaction.commit() // バックスタックへの追加 val fragmentTransaction = supportFragmentManager.beginTransaction() fragmentTransaction.addToBackStack("") fragmentTransaction.commit()
上記の例ではTransactionを定義する際にsupportFragmentManager.beginTransaction()
を使いましたが、これはこのまま使用して想定外のことが起きないでしょうか?次の章で説明します!
FragmentManagerの種類(アクセス)
FragmentManagerには、使用するフラグメントの種類に対応したクラスがあります
公式ドキュメントに詳しく説明の記載がありますが、どこからアクセスされるかで使用するFragmentManagerが変わります。次のようにマッピング一覧で表されています
また上記の「使用するFragmentManagerの一覧」図にあるLevelの定義は次のように具体例があります
すべての FragmentActivity とAppCompatActivityなどのサブクラスActivity内でアクセスする場合には、getSupportFragmentManager()
メソッドを介して FragmentManager にアクセスします
Fragment内でアクセスする場合には2パターンあります
Fragment内でgetChildFragmentManager()
を介して子Fragmentを管理するFragmentManagerへの参照を取得するパターンとそのホストであるFragmentManagerにアクセスする必要がある場合にはgetParentFragmentManager()
を使用するパターンです
今回自分はFragment内で子Fragmentを管理するパターンでgetSupportFragmentManager()
を使っていて表示がおかしくなっていました(BottomNavigationの1フラグメントの中でViewPagerを追加するという内容です)
一時的には表示がうまくいく可能性はありますが、リロードしたり、タブを切り替えて戻ってきたら表示されなくなるなど想定外のことがあり得ます。 FragmentManagerをどのように取得するかを意識して使うようにしましょう!