SavedStateHandle Integration¶
eungabi 0.4.0 introduces a powerful SavedState mechanism, enabling seamless state preservation and data transfer in conjunction with ViewModels. With this new feature, each ViewModel can now access a SavedStateHandle object, a key-value map that allows you to store and retrieve data directly within the ViewModel.
Crucially, the data within the ViewModelSavedState persists even through process termination and configuration changes, ensuring that your ViewModel's state remains intact.
Using SavedStateHandle in EunGabi¶
EunGabi provides several convenient ways to utilize SavedStateHandle for managing state across navigation events. Here are the primary methods:
1. Accessing SavedStateHandle via EunGabiController¶
You can access the SavedStateHandle of a specific EunGabiEntry by leveraging the EunGabiController.backStack. This allows you to retrieve the SavedStateHandle from any entry within the navigation back stack.
val controller = rememberEunGabiController()
val backStack by controller.backStack. collectAsState()
val handle = backStack.last().savedStateHandle
val viewModel = viewModel { ViewModel(handle) }
Explanation:
rememberEunGabiController(): Retrieves the currentEunGabiControllerinstance.controller.backStack.collectAsState(): Collects the current state of the back stack as aStateobject.backStack.last().savedStateHandle: Accesses theSavedStateHandleof the most recent entry in the back stack.viewModel { ViewModel(handle) }: Creates a ViewModel instance with the SavedStateHandle.
2. Accessing SavedStateHandle within NavGraphBuilder.composable()¶
Within the content block of NavGraphBuilder.composable(), you can directly access the SavedStateHandle of the current EunGabiEntry.
NavHost(...) {
composable(...) { entry ->
val handle = entry.savedStateHandle
val viewModel = viewModel { ViewModel(handle) }
}
}
Explanation:
composable(...) { entry -> ... }: Thecomposablefunction provides the currentEunGabiEntryas a parameter.entry.savedStateHandle: Directly accesses theSavedStateHandleassociated with the current entry.viewModel { ViewModel(handle) }: Creates a ViewModel instance with the SavedStateHandle.
3. Using Parameter Default Values with eunGabiViewModel()¶
For a more streamlined approach, you can use the eunGabiViewModel(...) function to inject the SavedStateHandle directly into your composable function's parameters.
eunGabiViewModel automatically recognizes the currently active EunGabiEntry and provides the corresponding SavedStateHandle.
@Composable
fun EunGabiScreen(
viewModel: EunGabiViewModel = eunGabiViewModel { handle -> EunGabiViewModel(handle) }
) { ... }
Explanation:
eunGabiViewModel { handle -> EunGabiViewModel(handle) }: This function automatically provides the correctSavedStateHandleto the lambda, which you can then use to create yourEunGabiViewModel.EunGabiViewModel(handle): Creates a EunGabiViewModel instance with the SavedStateHandle.
Hilt Integration¶
When using Hilt in your Android target, you can seamlessly inject the appropriate SavedStateHandle using hiltViewModel().
@Composable
fun HiltView(viewModel: HiltViewModel = hiltViewModel()) {
val state by viewModel.state.collectAsState()
Text(text = state, modifier = Modifier.testTag("state"))
}
hiltViewModel(): This Hilt function automatically provides the correctSavedStateHandleto yourHiltViewModel.viewModel.state.collectAsState(): Collects the current state of the ViewModel.
Tip
For a practical example of Hilt integration, refer to the EunGabiHiltTest.kt file in the EunGabi repository.
Koin Integration¶
Similarly, when using Koin in your KMP project, you can easily inject the SavedStateHandle using koinViewModel(). Koin, like Hilt, internally recognizes the current entry and provides the correct SavedStateHandle.
@Composable
fun KoinView(
viewModel: KoinViewModel = koinViewModel()
) {
val state by viewModel.state.collectAsState()
Text(text = state, modifier = Modifier.testTag("state"))
}
Explanation:
koinViewModel(): This Koin function automatically provides the correctSavedStateHandleto yourKoinViewModel.viewModel.state.collectAsState(): Collects the current state of the ViewModel.
Tip
For a practical example of Koin integration, refer to the KoinViewModelTest.kt file in the EunGabi repository.