Від 4 вересня 2024 року, коли вийшло оновлення 2.8.0, робити навігацію з передачею параметрів між екранами в Jetpack Compose стало набагато простіше. А також зручніше і зрозуміліше.
Раніше, щоб передати параметр з одного екрану на інший, потрібно було провести такі дії. На першому екрані передати щось на зразок цього:
Button(
onClick = {
navController.navigate("detail_screen/$text")
}
)
А якщо їх два, три? А якщо іноді він є, іноді немає?
Далі було цікавіше, цей параметр треба було прийняти, упакувати в список аргументів, і тут же дістати, визначити тип і аж тоді передати на наступний екран.
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, нічого не вийде). Код став читабельнішим, а писати зручніше.
Цей текст взято з особистого блогу після отримання дозволу автора.
Цей матеріал – не редакційний, це – особиста думка його автора. Редакція може не поділяти цю думку.












Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: