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

如何在Jetpack Compose中通过Hilt在运行时向ViewModel构造函数传参

解决Jetpack Compose+Hilt中ViewModel接收运行时Stop参数的问题

要实现将Stop对象传入ViewModel构造函数并在初始化时自动加载数据,需要借助Hilt的Assisted Injection来支持运行时参数传递。以下是具体实现步骤:

1. 添加Assisted Injection依赖

在Module级别的build.gradle文件中添加以下依赖:

implementation "androidx.hilt:hilt-assisted:1.1.0"
kapt "androidx.hilt:hilt-compiler:1.1.0"

2. 修改ViewModel实现Assisted Injection

调整ViewModel的构造函数,用@Assisted标记运行时传入的Stop参数,同时创建对应的Assisted Factory来生成ViewModel实例。另外将_stop改为非空StateFlow,并在init块中自动触发数据加载:

@HiltViewModel
class StopTimesMapViewModel @Inject constructor(
    private val getStopTimesUseCase: GetStopTimesUseCase,
    @Assisted private val stop: Stop
): ViewModel() {

    private val _stop = MutableStateFlow(stop)
    private val _estimations = MutableStateFlow<Resource<List<StopEstimation>>>(Resource.loading())

    val uiState: StateFlow<StopTimesMapUIState> = combine(_stop, _estimations) { stop, estimations ->
        StopTimesMapUIState(
            name = "${stop.id} - ${stop.name}",
            estimations = estimations.data ?: emptyList(),
            status = estimations.status
        )
    }.stateIn(
        scope = viewModelScope,
        started = WhileUiSubscribed,
        initialValue = StopTimesMapUIState(
            name = "${stop.id} - ${stop.name}"
        )
    )

    init {
        loadStopEstimations()
    }

    private fun loadStopEstimations() {
        viewModelScope.launch {
            getStopTimesUseCase(stop.id)
                .collect { estimations ->
                    _estimations.value = estimations
                }
        }
    }

    @AssistedFactory
    interface Factory : AssistedViewModelFactory<StopTimesMapViewModel> {
        override fun create(assistedParams: SavedStateHandle, stop: Stop): StopTimesMapViewModel
    }

    companion object {
        fun provideFactory(
            factory: Factory,
            stop: Stop,
            savedStateHandle: SavedStateHandle
        ): ViewModelProvider.Factory = object : ViewModelProvider.Factory {
            @Suppress("UNCHECKED_CAST")
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                return factory.create(savedStateHandle, stop) as T
            }
        }
    }
}

3. 在Composable中传递Stop参数创建ViewModel

修改StopTimesMapScreen,使用自定义的Factory将stop参数传入ViewModel:

@Composable
fun StopTimesMapScreen(
    modifier: Modifier = Modifier,
    stop: Stop,
    onDismissListener: (() -> Unit),
    viewModel: StopTimesMapViewModel = viewModel(
        factory = StopTimesMapViewModel.provideFactory(
            factory = hiltViewModel(),
            stop = stop,
            savedStateHandle = rememberSavedStateHandle()
        )
    )
) {
    val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)

    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    ModalBottomSheet(
        modifier = modifier,
        onDismissRequest = onDismissListener,
        sheetState = sheetState
    ) {
        StopEstimations(status = uiState.status, estimations = uiState.estimations)
    }
}

实现效果

  • Stop参数变为非空类型,无需处理空值逻辑
  • ViewModel初始化时自动调用UseCase加载数据,无需在Composable中手动调用loadStop
  • 完全遵循Hilt依赖注入规范,同时支持运行时参数传递

内容的提问来源于stack exchange,提问作者Javier Cancio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:33:31