Від 4 вересня 2024 року, коли вийшло оновлення 2.8.0, робити навігацію з передачею параметрів між екранами в jetpack compose стало набагато простіше. А також зручніше і зрозуміліше
Раніше, щоб передати параметр з одного екрану на інший, потрібно було провести такі дії. На першому екрані передати щось на зразок цього:
Button(
onClick = {
navController.navigate("detail_screen/$text")
}
)
А якщо їх 2, 3? А якщо іноді він є, іноді немає?
Далі було цікавіше, цей параметр треба було прийняти, упакувати в список аргументів, і тут же дістати, визначити тип і аж тоді передати на наступний екран.
NavHost(navController = navController, startDestination = "input_screen") {
...
composable(
"detail_screen/{inputText}",
arguments = listOf(navArgument("inputText") {
type = NavType.StringType
})
) { backStackEntry ->
val inputText = backStackEntry.arguments?.getString("inputText") ?: ""
SecondScreen(inputText)
}
По суті, якщо вам було потрібно передавати data class як параметр, його потрібно було серіалізувати в json з допомогою будь-якого серіалізатора, а на іншому боці провести зворотні дії. Це було не так складно, але виглядало наче щось десь робиться не через те місце.
Роути:
//Було
const val FIRST = "first"
const val SECOND = "second/{parameter}"
// Стало
@Serialisable
data object First
@Serialisable
data class Second(val parameter:T)
На стороні екрану
Button(
onClick = {
navController.navigate(Second(parameter)
}
)
На стороні NavHost
//якщо треба передати на екран
NavHost(navController = navController, startDestination = First) {
composable<Second>{ backStackEntry ->
val parameter = backStackEntry.toRoute<Second>().parameter
SecondScreen(parameter)
}
}
//якщо треба передати у в'юмодель
NavHost(navController = navController, startDestination = First) {
composable<Second>{
SecondScreen()
}
}
clas SecondViewModel(savedStateHandle: SavedStateHandle):ViewModel(){
val parameter = savedStateHandle.toRoute<Second>().parameter
}
При такому підході параметр ви отримуєте гарантовано. Додатково перевіряти його на null не потрібно, а можна одразу використовувати.
Об’єм даних, що можна передавати обмежений розміром bundle і досі становить 1 Мb. У параметри data calass`ів можна передавати дані стандартних типів та їх списки. Звісно, можна і кастомні, але складно, і в більшості випадків, не має необхідності.
То ж, що у нас у підсумку. Що змінилось? По суті - нічого. Але серіалізацію-десеріалізацію заховали “під капот” ( тепер треба використовувати kotlin serialisation, нічого не вийде). Код став читабельнішим, а писати зручніше.
Ви вже спробували оновлення? Поділіться враженнями