Jetpack Composeで画面遷移時にオブジェクトを渡して遷移したい
intentやargumentで今までできたのでやろうとしたらNavigationだとできないみたい
そんなわけでやり方
・dataの渡し方
複雑なパラメーターは渡せないので一回jsonにする
まじかって思うけど、まじらしい
https://stackoverflow.com/questions/65610003/pass-parcelable-argument-with-compose-navigation
呼ぶ側
val json = Uri.encode(Gson().toJson(a))
navController.navigate("hogehoge/$json")
受け取る側
composable(route = "hogehoge/fugafuga",
arguments = listOf(
navArgument("fugafuga") {
type = AType()
}
)
) { backStackEntry ->
val a = backStackEntry.arguments?.getParcel("fugafuga", A::class.java)
?: return@composable
class AType : NavType<A>(isNullableAllowed = false) {
override fun get(bundle: Bundle, key: String): A? {
return bundle.getParcel(key, A::class.java)
}
override fun parseValue(value: String): A {
return Gson().fromJson(value, A::class.java)
}
override fun put(bundle: Bundle, key: String, value: A) {
bundle.putParcelable(key, value)
}
}
・Parcelable
CREATORを作る必要があるが、別で定義してると自動補完が効かない
なので以下のように実装する
https://stackoverflow.com/questions/58725845/kotlin-multiple-named-companion-objects
companion object {
private const val a = "a"
@JvmField
val CREATOR = object: Parcelable.Creator<A> {
override fun createFromParcel(parcel: Parcel): A {
return A(parcel)
}
override fun newArray(size: Int): Array<A?> {
return arrayOfNulls(size)
}
}
}
・getParcelableExtraはdeprecated
https://stackoverflow.com/questions/73019160/the-getparcelableextra-method-is-deprecated
fun <T: Parcelable> Bundle.getParcel(key: String, clazz: Class<T>): T? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
this.getParcelable(key, clazz)
} else {
@Suppress("DEPRECATION") this.getParcelable(key)
}
}
関連記事:
- ProgressDialogがdeprecatedになったので、DialogFragmentを拡張して作った
- DaggerのAndroid Supportを使ってみた
- Activity Result APIを使ってカスタムコントラクトを作成する