Hi, i'm trying to use this <BackStack> implementat...
# compose
s
Hi, i'm trying to use this BackStack implementation from Adam Powell's Gist, but when i use ViewModel with each route it's giving me IllegalArgumentException SavedStateProvider with the given key is already registered, when i come back to same route again, what could be reason for this ?
Here how i define hiltViewModel composable
Copy code
@Composable
public inline fun <reified T : ViewModel> hiltViewModel(viewModelProviderFactory: ViewModelProvider.Factory? = null) : T {
    val context = LocalContext.current
    val viewModelStoreOwner = LocalViewModelStoreOwner.current
    val owner = LocalSavedStateRegistryOwner.current

    return remember(key1 = T::class) {
        val activity = context.componentActivity
        val factory = NavigatorHiltViewModelFactories.getFactory(
            activity = activity,
            owner = owner,
            delegateFactory = viewModelProviderFactory
        )
        val provider = ViewModelProvider(viewModelStoreOwner ?: activity, factory)
        provider[T::class.java]
    }
}
Copy code
public object NavigatorHiltViewModelFactories {
    public fun getFactory(
        activity: ComponentActivity,
        owner: SavedStateRegistryOwner,
        delegateFactory: ViewModelProvider.Factory?
    ): ViewModelProvider.Factory {
        return EntryPoints.get(activity, ViewModelFactoryEntryPoint::class.java)
            .internalViewModelFactory()
            .fromActivity(activity, owner, delegateFactory)
    }

    internal class InternalViewModelFactory @Inject internal constructor(
        private val application: Application,
        @HiltViewModelMap.KeySet private val keySet: Set<String>,
        private val viewModelComponentBuilder: ViewModelComponentBuilder
    ) {
        fun fromActivity(
            activity: ComponentActivity,
            owner: SavedStateRegistryOwner,
            delegateFactory: ViewModelProvider.Factory?
        ): ViewModelProvider.Factory {
            val defaultArgs = activity.intent?.extras
            val delegate = delegateFactory ?: SavedStateViewModelFactory(application, owner, defaultArgs)
            return HiltViewModelFactory(owner, defaultArgs, keySet, delegate, viewModelComponentBuilder)
        }
    }

    @EntryPoint
    @InstallIn(ActivityComponent::class)
    internal interface ViewModelFactoryEntryPoint {
        fun internalViewModelFactory(): InternalViewModelFactory
    }
}
Copy code
val backStack = rememberSaveableBackStack {
    push(SaveableBackStack.Record("Home"))
}
Navigator(backStack) {
    route("Home") {
        val hiltViewModel = hiltViewModel<PackDetailViewModel>()
        Box(modifier = Modifier.fillMaxSize()) {
            Button(onClick = { backStack.push(SaveableBackStack.Record("Details")) }) {
                //Text("${hiltViewModel.uiState}")
            }
        }
    }

    route("Details") {
        val hiltViewModel = hiltViewModel<CategoryDetailViewModel>()
        Box(modifier = Modifier.fillMaxSize()) {
            Text("${hiltViewModel.uiState}")
        }
    }
}