0

how to shared viewmodel in NavGraphBuilder.navigation between dialog and composable?

my code

navigation(startDestination = Stage.First.name, route = "main") {
            dialog(Stage.First.name){
                it.provideViewModel<MyViewModel> { vm ->
                    MyDialog(vm)
                }
            }
            composable(Stage.Second.name) {
                it.provideViewModel<MyViewModel> { vm ->
                    Second(vm)
                }
            }
            composable(Stage.Third.name) {
                it.provideViewModel<MyViewModel> { vm ->
                    Third(vm)
                }
            }
            
        }


@Composable
inline fun <reified T : ViewModel> NavBackStackEntry.provideViewModel(
    content: @Composable (T) -> Unit
) {
    val parentId = destination.parent!!.id
    val parentEntry = remember(this) { navCon.getBackStackEntry(parentId) }

    val viewModel = hiltViewModel<T>(parentEntry)
    "vmHashcode".log("${destination.route} : ${viewModel.hashCode()}")

    content(viewModel)
}

This code is shared between composable and composable. But,it cannot be shared in composable and dialog.

Any solution?

1
  • I try to reproduce your code, it is indeed sharing the same instance of ViewModel. I believe there is nothing wrong in your code. When you create an instance of MyViewModel it's always use the same ViewModelOwner, which was your NavGraph. Keep in mind that your code will always return the same instance of ViewModel when your destination is still in the same scope of the NavHost Commented Oct 24, 2022 at 17:28

1 Answer 1

1

I think this code might help

//Activity 
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel: MyViewModel by viewModels()
        MyCustomTheme{
            Surface(modifier = Modifier.fillMaxSize()) {
                MyCustomNavGraph(
                    viewModel = viewModel,
                    startDestination = "START_DESTINATION"
                )
            }
        
        }

}


// NavGraph File
fun MyCustomNavGraph(
    viewModel: MyViewModel,
    startDestination: String = Routes.START_DESTINATION
) {
    navigation(startDestination = startDestination, route = "main") {
            dialog(Stage.First.name){
               MyDialog(viewModel)
            }
            composable(Stage.Second.name) {
               Second(viewModel)
            }
            composable(Stage.Third.name) {
                Third(viewModel)
            }
            
        }
}

As @axelbrians mentioned you need to use the same instance of view model if you are in same scope of nav host

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.