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

Android:如何在Hilt ViewModel中直接传递自定义导航参数?

可行,直接通过ViewModel构造函数接收导航参数

不需要用LaunchedEffect传递参数,你可以借助Hilt结合SavedStateHandle,直接在ViewModel的构造函数中获取导航参数。具体实现步骤如下:

1. 修改ViewModel,通过SavedStateHandle接收参数

在ViewModel的构造函数中注入SavedStateHandle,导航参数会自动存储在这个对象里,直接从中读取即可:

class ProfileDisplayScreenViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
    private val interActor: YourInterActorType // 替换成你的实际依赖类型
) : ViewModel() {
    // 从SavedStateHandle获取导航参数,key要和导航时传递的一致
    private val profileId: Int = savedStateHandle.get<Int>("profile_id")!!

    // 直接用参数初始化状态流
    val uiState: StateFlow<ProfileUiState> = flow {
        val profileData = interActor.getProfileData(profileId)
        emit(ProfileUiState.Loaded(profileData))
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000),
        initialValue = ProfileUiState.Loading
    )
}

注意:如果参数是可选的,不要用!!强制拆包,改用getOrDefault("profile_id", 默认值)或者getOrNull()做空安全处理。

2. 确保导航时正确传递参数

导航到目标屏幕时,要把参数附加到路由上(或用类型安全参数):

// 拼接参数到路由,key和ViewModel中用的保持一致
navController.navigate("${AppScreens.InfoScreen.route}?profile_id=$targetProfileId")

如果使用类型安全导航(推荐),可以在导航图定义时指定参数,生成的导航函数会自动处理参数传递,避免硬编码字符串key。

3. 简化Composable中的ViewModel调用

现在不需要LaunchedEffect,直接获取ViewModel即可,参数已经在ViewModel初始化时处理完成:

Screen(AppScreens.InfoScreen.route) {
    val viewModel = hiltViewModel<ProfileDisplayScreenViewModel>()
    val uiState by viewModel.uiState.collectAsState()
    ProfileDisplayScreen(uiState, viewModel.interActor)
}

原理说明

Hilt的hiltViewModel()会自动关联当前导航栈条目的SavedStateHandle,导航组件默认会将路由参数存入这个SavedStateHandle,因此ViewModel可以在构造阶段直接读取参数,无需在Composable中额外传递。

内容的提问来源于stack exchange,提问作者Gulab Sagevadiya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:43:11