Нова навігація в Jetpack Compose на Android

Євгеній Маслак

Від 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, нічого не вийде). Код став читабельнішим, а писати зручніше.

Цей текст взято з особистого блогу після отримання дозволу автора.

Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту та натисніть Ctrl+Enter.

Останні статті

CSR у Next.js. Як працює і що у нього під капотом

Зайшов на сторінку, а там — спінери, skeleton і порожнеча? Це не баг, це —…

31.07.2025

Чому я пишу про факапи?

Таке запитання мені поставив мій знайомий, коли побачив мій профіль. Я настільки над цим задумалась,…

30.07.2025

Як налаштувати штучний інтелект з унікальною базою знань? (безкоштовно)

Нещодавно я вписався в один цікавий проєкт. Довелося розібратись з процесом звітності американських фармацевтичних компаній…

29.07.2025

Одного разу я сильно посварився з СЕО компанії або Коли треба вчасно зупинитися і вміти сказати «ні»

Одного разу я сильно посварився з СЕО компанії. Він кричав на мене, а я у…

28.07.2025

Навіщо тестові, коли є портфоліо?

Одразу два офтопи: Я також виконувала тестові; Тестове має бути коротким, чітким, і, бажано, оплачуваним.…

25.07.2025

Припиніть писати код, як ніби ви працюєте в Google

Давайте відразу розставимо крапки над «і». Ви не працюєте в Google. Я теж. Більшість з…

24.07.2025