2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Fragmentの画面遷移のおさらい

Last updated at Posted at 2019-09-16

やること

Fragmentの画面遷移で単純に A -> B の画面遷移と A <- B のように
1つ前の画面に戻るのはすぐ理解できるのに
A -> B -> C の後に A <- (B) <- C のように C から A に戻るのが苦戦するので
メモを残すことにしました。
(Webアプリでよくある 
 一覧画面(A) -> 詳細画面(B) -> 変更画面(C) -> 確認画面(D) -> 一覧画面(A)
 のようなパターンだけど、アプリでも類似のものは意外と出くわす印象があります。)

作ったアプリ

https://github.com/shinya-takano/FragmentSample



単純に画面遷移するアプリですが、
画面Dから画面Aに遷移し、画面B・画面Cには戻れないようにしました。
(よくある、編集中の画面には戻れないようにする作り)

理解したこと

1. FragmentManagerはstackでした

FragmentD.kt
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.d("FragmentD", "onViewCreated")

        val backStackEntryCount = getMainActivity()?.supportFragmentManager?.backStackEntryCount ?: 0
        for (index in 0 until backStackEntryCount) {
            val backStackEntry = getMainActivity()?.supportFragmentManager?.getBackStackEntryAt(index)
            Log.d("FragmentD", "index=$index name=${backStackEntry?.name}")
        }

このコードのログが以下です。stackだと理解できました..

FragmentD: onViewCreated
FragmentD: index=0 name=FragmentA
FragmentD: index=1 name=FragmentB
FragmentD: index=2 name=FragmentC
FragmentD: index=3 name=FragmentD

2. A画面に戻る場合は、B画面までのstackをpopすると理解すると良さそうです..多分

FragmentD.kt
        button3.setOnClickListener {
            // fragmentManager から pop したい Fragment の tag を取得(popした後のFragmentが表示される)
            val tag = getMainActivity()?.supportFragmentManager?.getBackStackEntryAt(1)?.name
            Log.d("FragmentD", "tag=$tag")
            getMainActivity()?.supportFragmentManager?.popBackStack(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE)
        }

実行時のログは以下のようになります。tagにFragmentBを指定すると、FragmentBまでが消えて、
FragmentAが表示されます。

FragmentD: tag=FragmentB
FragmentA: onCreateView
FragmentA: onViewCreated

所感

画面Aに遷移したいからといって、画面AのFragmentをpopBackStack(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE)してハマってました。
きちんと挙動を理解すれば、癖も把握できるのでやっぱりサンプルで理解を深めるのは
大事だと思いました。

その他

Fragmentの拡張関数を用意しておくと、addBackStackなどは楽そうなので、参考までに。

FragmentExtension.kt
fun Fragment.getBackStackTag(): String {
    return this.javaClass.simpleName
}
MainActivity.kt
    fun replaceFragment(fragment: Fragment) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.container, fragment)
            .addToBackStack(fragment.getBackStackTag())
            .commit()
    }

参考

自分でサンプルコード作る前まではこちらの記事を参考にしてました。
こちらの記事の方がわかりやすいと思います...
https://qiita.com/tomo1139/items/62902093d1850085742d

こちらは内部処理にも言及していて、とても参考になりました。
http://nein37.hatenablog.com/entry/2018/05/06/204943

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?