I have such an implementation:
...
@Composable
private fun PhoneVerificationCodeScreen(vm: MyViewModel) {
Column(...) {
...
OTPBlock(numberOfCells = NUMBER_OF_OTP_CELLS, isVerifyBtnEnabledState = vm.isVerifyBtnEnabledState)
...
}
}
...
There is my preview function:
class MyViewModelProvider : PreviewParameterProvider<MyViewModel> {
override val values: Sequence<MyViewModel> = sequenceOf(MyViewModel(
SavedStateHandle()
))
}
@Preview(
name = "Phone-portrait",
device = Devices.PHONE,
showBackground = true,
backgroundColor = 0x111,
showSystemUi = true
)
@Composable
private fun PhonePreviewVerificationCodeScreen(
@PreviewParameter(MyViewModelProvider::class) vm: MyViewModel
) = PhoneVerificationCodeScreen(vm = vm)
SPOILER: before I included ViewModel as a param it worked as expected.
I went through a few solutions in the google and the last one I tried was by using PreviewParameterProvider
, however, it doesn't work as well.
So, the question is - how to "preview" the compose function that takes a param?
ERROR is:
java.lang.ClassNotFoundException: my_package.VerificationCodeViewModelProvider at java.lang.ClassLoader.loadClass at java.lang.ClassLoader.loadClass at java.lang.Class.forName0 at java.lang.Class.forName at androidx.compose.ui.tooling.ComposableInvoker.invokeComposable
The method recommended on the Android developers site for creating previews of composables with ViewModels is to create an inner composable that accepts the ViewModel parameters as arguments:
@Composable
fun MyComposable(viewModel: MyViewModel) {
val state by viewModel.state.collectAsStateWithLifecycle()
MyComposable(
state = state
)
}
@Composable
fun MyComposable(state: MyState) {
...
}
Then create a preview for the inner composable:
@Preview
@Composable
fun MyComposablePreview(state: MyState = MyState()) {
MyComposable(state = state)
}
See: https://developer.android.com/jetpack/compose/tooling/previews#preview-viewmodel
There are various other methods as well, such as using an interface and creating a preview instance of the interface.