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

如何在HorizontalPager中向hiltViewModel()传递参数?

在HorizontalPager中为每个页面创建独立的Hilt ViewModel实例

要实现HorizontalPager每个页面拥有独立的PageViewModel实例并传入页面ID,核心是为每个页面提供独立的ViewModelStoreOwner,同时将ID注入到ViewModel的SavedStateHandle中,具体实现如下:

1. 为每个Pager页面创建独立的ViewModelStoreOwner

在ListScreen的HorizontalPager中,为每个页面绑定唯一的ViewModelStoreOwner,确保不同页面的ViewModel实例相互隔离:

@Composable
fun ListScreen(viewModel: ListViewModel = hiltViewModel()) {
    val myIds: List<Int> by viewModel.ids.collectAsState(emptyList())

    HorizontalPager(
        pageCount = myIds.size,
    ) { index ->
        val pageId = myIds[index]
        // 基于pageId创建独立的ViewModelStoreOwner,页面切换时自动复用/销毁
        val pageViewModelStoreOwner = remember(pageId) {
            object : ViewModelStoreOwner {
                private val store = ViewModelStore()
                override val viewModelStore: ViewModelStore
                    get() = store
            }
        }
        PageScreen(pageId, pageViewModelStoreOwner)
    }
}

2. 在PageScreen中注入ID到ViewModel的SavedStateHandle

修改PageScreen,通过hiltViewModel的creationCallback将页面ID存入SavedStateHandle,同时指定独立的ViewModelStoreOwner:

@Composable
fun PageScreen(
    id: Int,
    viewModelStoreOwner: ViewModelStoreOwner,
    viewModel: PageViewModel = hiltViewModel(
        viewModelStoreOwner = viewModelStoreOwner,
        creationCallback = { factory ->
            val savedStateHandle = SavedStateHandle().apply {
                set("page_id", id)
            }
            factory.create(PageViewModel::class.java, savedStateHandle)
        }
    )
) {
    // 页面逻辑,可直接使用viewModel中的pageId
}

3. 在PageViewModel中获取页面ID

从SavedStateHandle中取出传入的ID,用于后续业务逻辑:

@HiltViewModel
class PageViewModel 
@Inject constructor(
    val savedStateHandle: SavedStateHandle
): ViewModel() {
    // 从SavedStateHandle获取页面ID,非空校验确保业务安全
    val pageId: Int = checkNotNull(savedStateHandle["page_id"])
    
    // 业务逻辑示例:根据pageId加载对应数据
    // val pageData = flow { ... }
}

关键说明

  • 独立的ViewModelStoreOwner确保每个页面的ViewModel实例完全隔离,不会因Pager页面复用而共享状态。
  • 使用remember(pageId)绑定ViewModelStoreOwner的生命周期,当页面滑出屏幕超过offscreenLimit时,对应的ViewModel会自动销毁,符合Compose的生命周期管理。
  • 通过SavedStateHandle传递ID,遵循Hilt ViewModel的设计规范,同时支持状态持久化(如配置变更时保留ID)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:55:20