권오성
권오성

Reputation: 51

Android compose how to shared viewmodel on navigation between dialog and composable?

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?

Upvotes: 0

Views: 594

Answers (1)

Akhil Krishnan
Akhil Krishnan

Reputation: 73

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

Upvotes: 1

Related Questions