Fragment間でデータを受け渡す方法でArguments()とsetFragmentResultListener()があります。使い方をメモします。
replaceで次のFragmentへ遷移する
FragmentAからFragmentBへ遷移し、データを渡す場合は、argumentsを利用します。
val fragment = FragmentB().apply {
arguments = bundleOf(
"userId" to 100
)
}
parentFragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit()
FragmentBでは以下のように取得できます。
val userId = requireArguments().getInt("userId")
popBackStackで前のFragmentへ戻る
次にはFragmentBからFragmentAへ戻るときにデータを渡す方法です。この場合はsetFragmentResult()を使用します。
戻り元となるFragmentAでListenerを登録します。
parentFragmentManager.setFragmentResultListener("user_result", this) { _, bundle ->
val userId = bundle.getInt("userId")
// 処理が続く
}
FragmentBでは、戻る前に以下のようにsetFragmentResult()でデータを渡します。
parentFragmentManager.setFragmentResult("user_result", bundleOf("userId" to 100))
parentFragmentManager.popBackStack()
これで、前のFragmentが再表示されたときに結果を受け取ることができます。
setFragmentResult()で設定した結果はFragmentManagerによって保持されます。
自作のData Classを渡す
setFragmentResultListener()はStringやIntなど値だけでなく、自作のData Classも渡すことができます。
以下のUserを定義します。
@Parcelize
data class User(
val id: Int,
val name: String,
val age: Int
) : Parcelable
FragmentBでUserを作成し、setFragmentResult()で渡します。
val user = User(
id = 100,
name = "Taro",
age = 30
)
parentFragmentManager.setFragmentResult("user_result", bundleOf("user" to user))
parentFragmentManager.popBackStack()
FragmentAでBundleからUserを取得します。Android 13(API 33)以降と、それ以前でgetParcelable()の呼び出し方を変えます。
これで、自作したData classをFragment間で受け渡すことができます。
parentFragmentManager.setFragmentResultListener("user_result", this) { _, bundle ->
val user = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
bundle.getParcelable("user", User::class.java)
} else {
@Suppress("DEPRECATION")
bundle.getParcelable("user")
}
user?.let {
// 処理が続く
}
}