Нова навігація в Jetpack compose на android

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

Ви вже спробували оновлення? Поділіться враженнями

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Євгеній Маслак
Євгеній Маслак@maslak

11Прочитань
0Автори
0Читачі
На Друкарні з 15 серпня

Більше від автора

Вам також сподобається

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Вам також сподобається