概要
前回までで、2つの fragmentを作つた。いづれも、ボタンを有し、それを押すと、fragment が交互に切り替はることを確認した。
ここでは、addToBackStack( )を用ひて、遷移を保存してみる。また、遷移の都度、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③とが破棄される振る舞ひになつてゐる。
すつきりとせぬまま終る。
(了)
0 件のコメント:
コメントを投稿