You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为带参数的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:22:33