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

如何为自定义DialogFragment设置泛型<T: ViewModel>作为构造入参

实现方案

你需要的泛型化传入任意ViewModel的CustomDialogFragment有两种实现方式,分别适配不同的使用场景:

方案1:构造直接传入ViewModel(仅适用于无需处理配置变更重建的场景)

如果你的App禁用了横竖屏切换,不需要考虑DialogFragment被系统重建的场景,可以直接按预期写法实现:

定义Dialog代码

import androidx.lifecycle.ViewModel
import androidx.fragment.app.DialogFragment

class CustomDialog<T : ViewModel>(private val viewModel: T) : DialogFragment() {
    // 此处编写Dialog的业务逻辑,直接调用viewModel即可,类型为传入的泛型T
}

调用代码

// 传入ViewModelA实例
val mDialog1: CustomDialog<ViewModelA> by lazy { CustomDialog(viewModel as ViewModelA) }
// 传入ViewModelB实例
val mDialog2: CustomDialog<ViewModelB> by lazy { CustomDialog(viewModel2 as ViewModelB) }

注意:该方案存在缺陷,当触发配置变更(横竖屏切换、系统语言更改等)导致Dialog被系统销毁重建时,系统会调用无参构造方法,传入的ViewModel实例会丢失,可能引发崩溃。

方案2:官方规范实现(推荐,支持配置变更)

该方案不需要直接传入ViewModel实例,由Dialog内部从宿主(父Fragment/Activity)的作用域自动获取对应类型的ViewModel,完全符合Android开发规范:

定义Dialog代码

import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.fragment.app.DialogFragment

class CustomDialog<T : ViewModel>(private val viewModelClass: Class<T>) : DialogFragment() {
    // 和宿主共用同一个ViewModel实例,生命周期和宿主绑定
    val viewModel: T by viewModels(
        // 若需要和Activity共用ViewModel,将ownerProducer改为{ requireActivity() }
        ownerProducer = { requireParentFragment() }
    )

    companion object {
        fun <T : ViewModel> create(viewModelClass: Class<T>): CustomDialog<T> {
            return CustomDialog(viewModelClass)
        }
    }

    // 此处编写Dialog的业务逻辑,直接调用viewModel即可
}

// Kotlin 简化调用的扩展方法(可选)
inline fun <reified T : ViewModel> createCustomDialog(): CustomDialog<T> {
    return CustomDialog.create(T::class.java)
}

调用代码

// 创建持有ViewModelA的Dialog
val mDialog1 by lazy { createCustomDialog<ViewModelA>() }
// 创建持有ViewModelB的Dialog
val mDialog2 by lazy { createCustomDialog<ViewModelB>() }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 09:24:06