概要
先日リリースされた、Navigationライブラリーの 2.8.0-alpha08から navigation-compose
でも型安全機能である、 Safe Args
が導入されたため、検証してみました。
従来の navigation-compose
では、画面遷移時に引数を渡す際に型チェックが十分に行われず、意図せぬ型エラーが発生してしまう可能性がありました。しかし、 Safe Args
の導入により、安全に引数を渡せるようになり、アプリ開発における保守性と安全性が大幅に向上します。
Safe Argsとは?
Navigation Fragment 時代には、Safe Args
を使用することでデータ渡しを型安全で受け渡しすることができました。
実装例
HomeFragment.kt
override fun onClick(view: View) {
val amount = binding.amount.text.toString()
val action = HomeFragmentDirections.DetailAction(amount)
view.findNavController().navigate(action)
}
DetailFragment.kt
val args: DetailFragmentArgs by navArgs()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val amount = args.amount
binding.amount.text = amount
}
Compose ではどうしていたか
Safe Args
がないため、 navigation-compose
では、ディープリンクのように目的地のパスに対し、引数を渡してました。
実装例
HomeScreen.kt
composable("home") {
HomeScreen(navController)
}
@Composable
fun HomeScreen(navController: NavHostController) {
Button(
onClick = { navController.navigate("detail?amount=10000") }
) {
Text("詳細画面へ遷移")
}
}
DetailSreeen.kt
composable(
route = "detail/{amount}",
arguments = listOf(
navArgument("amount") {
type = NavType.LongType
}
)
) { backStackEntry ->
val amount = backStackEntry.arguments?.getLong("amount") ?: 0L
DetailScreen(amount)
}
@Composable
fun DetailScreen(amount: Long) {
Text("金額: $amount")
}
これからは
Serializable
クラスとして、Routeを定義するようになり、このクラスに渡したいデータを詰めることで、型安全で値を受け取れるようになります。
実装例
HomeScreen.kt
@Serializable
object Home
composable(Home) {
HomeScreen(navController)
}
@Composable
fun HomeScreen(navController: NavHostController) {
Button(
onClick = { navController.navigate(Detail(10000)) }
) {
Text("詳細画面へ遷移")
}
}
DetailScreen.kt
@Serializable
data class Detail(val amount: Long = 0L)
composable<Detail> { backStackEntry ->
val amount = backStackEntry.toRoute<Detail>().amount
DetailScreen(amount)
}
@Composable
fun DetailScreen(amount: Long) {
Text("金額: $amount")
}
まとめ
Safe Args
は、まだalpha版であり、まだ変更される可能性があるため、本番環境での利用は注意が必要です。
ですが、型安全で受け渡しができるのはとても魅力的ですので、使用していきたいですね!