概要
前回までで、第一の Fragment から第二の Fragment に画面が遷移するところまでを作つた。 今回は、逆に、第二の Fragment から第一の Fragment に遷移するところを作る。 作業自体は、前回とほぼ同じことの繰り返しになる。
最後に、このプログラムの潜在的な問題に触れる。
使ふているバージョンは同じく次。
Android Studio : 3.5.2
Kotlin : 1.3.61
第二のFragmentのコード実装 - SecondFragment.kt
既に、第二のFragmentのレイアウトは fragment_second.xmlとして前回までに作成済。ボタン部品のidは button2として設定済。 あとは、MainFragment.ktで行つたのと同じやうに、listtenerインタフェースを準備し、ボタンのイベント listenerの設定を行ふ。
SecondFragment.ktのコードは次の通り。
class SecondFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_second, container, false)
val button2 = view.findViewById<Button>(R.id.button2)
button2.setOnClickListener {
val listener = context as? OnButtonClickListener2
listener?.onButtonClicked2()
}
return view
}
interface OnButtonClickListener2 {
fun onButtonClicked2()
}
override fun onDestroy() {
Log.i("mylog", "SecondFragment:onDestroy")
super.onDestroy()
}
}
- 13行目:
- インタフェースの名称は、onButtonClickListener2としている。
- 23行目
- MainFragment.ktの場合と同様、この fragmentがdestroyされてゐることを確認するために、onDestroy( ) call back関数を実装し、その中でログを表示してゐる。
ボタン イベント処理 - MainActivity.kt
第二の fragmentのボタンが押されたら、MainFragmentに戻る処理を実装する。 やることは、MainFragmentから第二の fragmentに遷移する実装と同じ。 既に SecondFragment.ktで定義したインタフェースの onButtonClickListener の実装になる。MainActivity.ktのコードは次のやうになる。
class MainActivity : AppCompatActivity(), MainFragment.OnButtonClickListener,SecondFragment.OnButtonClickListener2 {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
override fun onButtonClicked() {
Log.i("mylog", "onButtonClicked")
val secondFragment = SecondFragment()
supportFragmentManager.beginTransaction().replace(R.id.container, secondFragment).commitNow()
}
override fun onButtonClicked2() {
Log.i("mylog", "onButtonClicked2")
supportFragmentManager.beginTransaction().replace(R.id.container,MainFragment.newInstance()).commitNow()
}
}
- 1行目
- MainActivityでは、第二のfragmentの fragment_second.ktで定義したインタフェース SecondFragment.OnButtonClickListener2の派生でもあるのでこれを追加。
- 20行目:
- MainFragmentに切り替へる処理。
ここまででビルドし実行。
動作の確認 Fragmentの破棄と戻るボタンでアプリ終了
動作させてみる。
第一の Fragment の画面にある To Second Fragmentのボタンを押して、画面が 第二のFragmentに切り替はることを確認する。また、その切り替はるときに、Logcatのウィンドウで、MainFragmentが破棄(destroy) されることも確認する。
次に、第二の fragmentの画面で、To Main Fragmentのボタンを押し、画面が第一の Fragment に切り替はることを確認する。その切り替はりのときに、Logcatのウィンドウで、SecondFragment が破棄(destroy) されることも確認する。
最後に、それぞれの Fragmentの画面で、戻るボタンを押すと、アプリケーションが終了することも確認する。
設計動作
ここまでで、次のことを理解する。
- 画面が切り替はる都度、新たな fragmentの実体が生成され表示されてゐること
- 切り替はる前の画面は、都度、破棄 (destroy) されてゐること
- 同時には常に1つの fragment だけが存在し表示されていること
- 戻るボタンでアプリケーションが終了すること
これが期待した設計ならば、設計どほりに動作してゐることになる。
隠れた問題
第二の Fragmentで、戻るボタンを押すと、アプリが終了するのではなく、最初の Fragmentに切り替はるやうに作り変へたいとする。 そのための支援関数として addToBackStack ( ) といふものある。しかし、これをそのまま使ふと、動作がおかしくなる。具体的には、画面が切り替はるたびに、古い Fragment が破棄されないまま、次の新しい Fragment が作り続けられることが起こる。
これが期待動作でないならば、実装に誤りがあることになる。 つづく。
(了)
0 件のコメント:
コメントを投稿