Fragment 間の遷移 (4) 「戻る」ボタンでの戻りと fragmentの居座り

2019年12月15日日曜日

Android Kotlin

t f B! P L

概要

 前回までで、2つの fragmentを作つた。いづれも、ボタンを有し、それを押すと、fragment が交互に切り替はることを確認した。
 ここでは、addToBackStack( )を用ひて、遷移を保存してみる。また、遷移の都度、fragmentを生成することで不都合が起こることを確認する。


戻るボタンで前の fragmentに戻す - MainActivity.kt

実現すべき機能

実現したい機能は次とする。
  • 第一の fragment の表示中に戻るボタンを押すとアプリが終了する
  • 第二の fragment の表示中に戻るボタンを押すと、第一の fragmentに戻る

addToBackStack () の利用

 FragmentTransactionクラスの中の関数に addToBackStack ( ) がある。これは、fragment の遷移 (transaction)を スタックとして積み上げ式に記録する。記録するタイミングは、この関数が呼ばれた直後ではなく、そのあとで、commit( ) 関数が呼ばれたとき。
 戻るボタンが押されると、システムは、スタックに積まれた最新の、つまり、一番上の遷移を取り出して、その逆の遷移処理を行つてくれる。
 addToBackStack( )の、引数はその操作の名称、らしい。確認していない。通常は null を使ふ。別の関数に popToBackStack( ) といふものがあり、その引数で使ふ模様。

実装してみる - MainActivity.kt

 MainActivity.ktの中で定義した、第一の fragementの中のボタンが押されたときの処理にあたる onButtonClicked( )関数の中で、この addToBackStack( )を実行してみる。


override fun onButtonClicked() {
        Log.i("mylog", "onButtonClicked")
        val secondFragment = SecondFragment()
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.container, secondFragment)
        transaction.addToBackStack(null)
        transaction.commit()
}


  • 2行目:ログ表示
  • 3行目:第二の fragment の実体となる secondFragment を生成してゐる
  • 4行目:サポートライブラリのbeginTransaction()を使ふて FragmentTransactionの実体を得る。
  • 5行目:man_activity.xmlで定義した fragment の入れ物 (idはcontainer)の中の fragmentを 第二の fragmentの実体を置き換える。
  • 6行目:戻るためのスタックに 前の操作、つまり5行目の操作を積む。
  • 7行目:4〜6行目のtransactionの操作を実行する。

実行してみる

実行その1

 第一の fragmentで実装したボタンを押すと、 Second Fragmentに期待通り遷移する。 しかし、遷移した時に、これまで呼ばれてゐた MainFragmentの onDestroy ( )が呼ばれてゐないことが Logcatを見てわかる。といふことは、MainFragmentの実体は、破棄されていない。

実行その2

 第一の fragmentと 第二の fragmentとで、戻るボタンではなく、fragmentで実装したボタンを押して何度か行つたり来たりする。 onDestroy( )が一度も呼ばれないことを Logcatで確認する。

実行その3

 上記実行その2のやうに、第一と第二のfragmentの間で何度か往復をして、最後に、第二のfragment 画面にする。その後で、戻るボタンを何回か押す。すると、MainFragmentへの画面遷移が一度起こつたあとは、戻るボタンを押しても、MainFragmentが表示されたまま。ただし、押すたびに、SecondFragment の onDestroy( )が呼ばれることが確認できる。

起こつてゐること

上記の操作で起こっていることは次のやうになる。


画面表示   ボタン操作 スタック   スタック
             積上げ    取出し
-------------------------------------------
(起動)
 ↓     
 MF①
 ↓     To 2nd   MF①→SF①
 SF①
 ↓     To Main  
 MF②
 ↓     To 2nd   MF②→SF②
 SF②
 ↓     To Main  
 MF③
 ↓     To 2nd   MF③→SF③
 SF③
 ↓     もどる          SF③→MF③
 MF③
 ↓     もどる          SF②→MF②
 MF②
 ↓     もどる          SF①→MF①
 MF①
 ↓     もどる
 待受画面

  表記:MF①、MF②、MF③はMainFragmentの実体。最大3個の実体が生成される。
    SF①、SF②は、SecondFragmentの実体。最大2個の実体が生成。
    

 SecondFragmentの実体が破棄されずに残っているのは、スタックに遷移が残ることで、fragmentの実体への参照があるためと考へる。また、戻るボタン操作によつて、スタックからの遷移の取出しが実行されることで、参照が開放され、そのタイミングで SecondFragmentの実体が順次破棄されることになると考へる。

 MainFragmentについては謎が残る。もどるボタンを押すことで、確かに、記録された遷移が取り出され処理されてゐる。しかし、MainFragmentの実体は、onDestroy( )が呼ばれることない。最後に待ち受け画面に戻り、MainActivityの状態が stopになつたときに、MF②とMF③とが破棄される振る舞ひになつてゐる。

 すつきりとせぬまま終る。

(了)

アーカイブ