如何为带参数的Compose函数使用@Preview?遇类找不到异常
如何预览带参数的Compose函数
针对你碰到的带ViewModel参数的Compose预览问题,下面是几种可行的解决办法:
方案1:直接在预览里创建ViewModel实例
不用折腾PreviewParameterProvider,直接在预览函数里构造ViewModel实例传进去就行,简单高效:
@Preview( name = "Phone-portrait", device = Devices.PHONE, showBackground = true, backgroundColor = 0x111, showSystemUi = true ) @Composable private fun PhonePreviewVerificationCodeScreen() { val vm = MyViewModel(SavedStateHandle()) // 还能手动设置ViewModel状态,方便预览不同场景 vm.isVerifyBtnEnabledState.value = true PhoneVerificationCodeScreen(vm = vm) }
方案2:修复PreviewParameterProvider的访问问题
如果一定要用PreviewParameterProvider,先解决当前的类找不到问题:
- 检查报错里的
VerificationCodeViewModelProvider是不是笔误,确保@PreviewParameter里引用的是你实际定义的MyViewModelProvider - 把
MyViewModelProvider改成非私有顶层类(不要放在函数或类内部当私有内部类),因为Compose预览工具访问不到私有内部类:
// 放在文件最外层,不要嵌套在其他类/函数里 class MyViewModelProvider : PreviewParameterProvider<MyViewModel> { override val values: Sequence<MyViewModel> = sequenceOf( MyViewModel(SavedStateHandle()).apply { isVerifyBtnEnabledState.value = true } ) } // 预览函数保持原样即可 @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)
方案3:用Fake ViewModel做预览(复杂场景推荐)
如果真实ViewModel的构造逻辑复杂,或者想预览多种状态,建议专门写个预览用的FakeViewModel:
// 先抽个ViewModel的状态接口 interface VerificationViewModel { val isVerifyBtnEnabledState: MutableState<Boolean> } // 真实ViewModel实现这个接口 class MyViewModel(handle: SavedStateHandle) : ViewModel(), VerificationViewModel { override val isVerifyBtnEnabledState = mutableStateOf(false) // 其他业务逻辑 } // 预览专用的Fake类,想设置什么状态就改什么 class FakeVerificationViewModel : VerificationViewModel { override val isVerifyBtnEnabledState = mutableStateOf(true) } // 把屏幕函数的参数改成接口类型 @Composable private fun PhoneVerificationCodeScreen(vm: VerificationViewModel) { Column(...) { OTPBlock(numberOfCells = NUMBER_OF_OTP_CELLS, isVerifyBtnEnabledState = vm.isVerifyBtnEnabledState) } } // 预览直接用Fake类 @Preview( name = "Phone-portrait", device = Devices.PHONE, showBackground = true, backgroundColor = 0x111, showSystemUi = true ) @Composable private fun PhonePreviewVerificationCodeScreen() { PhoneVerificationCodeScreen(vm = FakeVerificationViewModel()) }
这种方式能隔离预览和真实业务逻辑,还能轻松切换不同状态预览,比如按钮启用/禁用的场景。
内容的提问来源于stack exchange,提问作者Sirop4ik
相关产品推荐
相关产品推荐

