How can i share data between navigation subgraph viewmodels in Android using Jetpack compose?

62 views Asked by At

Let`s assume that i have NavHost graph with subgraphs, in one subgraph i have several composables with their "local" route.

NavHost(
        navController = navController,
        startDestination = context.resources.getString(R.string.home_head_graph_route)
    ) {
        navigation(
            startDestination = "scanner",
            route = "scanner_head"
        ) {
            composable("scanner") {
                val scannerViewModel = it.sharedViewModel<QRCodeScannerViewModel>(navController)
                ...
            }

            composable("scanned_objects_list") {
                val scannerViewModel = it.sharedViewModel<QRCodeScannerViewModel>(navController)
                ...
            }
        }

        navigation(
            startDestination = "documents",
            route = "documents_head"
        ) {
            composable("documents") {
                val docsViewModel = it.sharedViewModel<DocsViewModel>(navController)
                ...
            }

            composable("other_doc_route") {
                val docsViewModel = it.sharedViewModel<DocsViewModel>(navController)
                ...
            }
        }
    }


//sharing viewModel inside subgraph, but when we leave this subgraph viewmodel will be cleared
@Composable
inline fun <reified T : ViewModel> NavBackStackEntry.sharedViewModel(navController: NavController): T {
    val navGraphRoute = destination.parent?.route ?: return hiltViewModel()
    val parentEntry = remember(this) {
        navController.getBackStackEntry(navGraphRoute)
    }
    return hiltViewModel(parentEntry)
}

I do some actions in "scanner" navigation graph and inserting some data from it in scannerViewModel, for example from this subgraph i get a list of scanned objects. How can I recieve this data in "documents" navigation graph from "scanner" navigation graph if scannerViewModel will be destroyed after I left from scanner graph? What should i do if i don't want to share viewModel above all navigation graphes like this:

    val scannerGlobalViewModel = hiltViewModel<QRCodeScannerViewModel>()
    NavHost(
        navController = navController,
        startDestination = context.resources.getString(R.string.home_head_graph_route)
    ) {
        navigation(
            startDestination = "scanner",
            route = "scanner_head"
        ) {...}

        navigation(
            startDestination = "documents",
            route = "documents_head"
        ) {...}
    }

I've tried to make viemodel shared above all navigation graphs, but then i think we lose advantages of subgraph logic isn't it? So how should i transfer my data from scanner graph viewModel in documents graph viewModel? How could I "connect" different viemodels from different subgraphs? Maybe should I store data for sharing between viewmodels in Room database? And in each viewModel has repository to get needed data?

0

There are 0 answers