I'm passing down a viewmodel to my composable, Now i can't use the preview anymore. The viewmodel is not needed for the preview but it is for the build.
How can i make my preview work again? Best / F
@Composable
fun MainNavigation(
settingsViewModel: SettingsViewModel,
isVisible: Boolean,
onDismiss: () -> Unit,
context: Context,
onResetCounters: () -> Unit
) {
}
@Preview(showBackground = true, name = "Main Navigation Preview")
@Composable
fun PreviewMainNavigation() {
val context = LocalContext.current
MainNavigation(
settingsViewModel = ,
isVisible = true,
onDismiss = {},
context = context,
onResetCounters = {}
)
}```
The official documentation has a dedicated section on Preview
with ViewModel
:
Previews are limited when using ViewModel within a composable. The previews system is not capable of constructing all of the parameters passed to a ViewModel, such as repositories, use cases, managers, or similar.
It also suggests what you can do instead:
If you want to preview a composable that uses a ViewModel, you should create another composable with the parameters from ViewModel passed as arguments of the composable.
In your case, this means that you create a separate Composable like this:
@Composable
fun MainNavigation(
settingsViewModel: SettingsViewModel,
isVisible: Boolean,
onDismiss: () -> Unit,
context: Context,
onResetCounters: () -> Unit
) {
MainNavigationContent(
viewModelPropertyA = settingsViewModel.settingA,
viewModelProperyB = settingsViewModel.settingB,
viewModelCallbackA = viewModel::onChange,
viewModelCallbackB = viewModel::onStringChange,
viewModelCallbackC = viewModel::onIntChange,
isVisible = isVisible,
onDismiss = onDismiss,
context = context,
onResetCounters = onResetCounters
)
}
// intermediate Composable that takes simple arguments instead of a ViewModel
@Composable
fun MainNavigationContent(
viewModelPropertyA: String, // adjust as needed
viewModelProperyB: Int,
viewModelCallbackA: () -> Unit,
viewModelCallbackB: (String) -> Unit,
viewModelCallbackC: (Int) -> Unit,
isVisible: Boolean,
onDismiss: () -> Unit,
context: Context,
onResetCounters: () -> Unit
) {
// other Composables
}
@Preview(showBackground = true, name = "Main Navigation Preview")
@Composable
fun PreviewMainNavigationContent() {
val context = LocalContext.current
MainNavigation(
settingsViewModel = /** ... **/,
isVisible = true,
onDismiss = {},
context = context,
onResetCounters = {}
)
}
This also is common practice, so avoid passing down a ViewModel, and instead pass down only the values and functions needed from the ViewModel.
Also check out this stackoverflow post for other suggestions, as depending on the complexity of your ViewModel, there might be workarounds so that you can still preview a ViewModel Composable directly.