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

Kotlin中如何在Kodein中配置多ViewModel的ViewModelFactory

解决Kodein中多ViewModelFactory的集中配置问题

你可以通过通用ViewModelFactory来避免为每个ViewModel单独创建Factory类,所有配置都能集中在Application的Kodein代码块里,具体实现如下:

1. 编写通用ViewModelFactory类

这个工厂类接受一个ViewModel的构造函数引用,负责创建对应的ViewModel实例,无需为每个ViewModel重复编写Factory:

class GenericViewModelFactory<VM : ViewModel>(
    private val viewModelProducer: () -> VM
) : ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return viewModelProducer() as T
    }
}

2. 在Kodein中集中配置所有ViewModel的工厂

在Application的Kodein懒加载块里,直接为每个ViewModel绑定对应的通用工厂,无需单独创建Factory类:

class AddSpendApplication: Application(), KodeinAware {
    override val kodein: Kodein = Kodein.lazy {
        import(androidXModule(this@AddSpendApplication))
        
        // 绑定基础依赖
        bind() from singleton { PersonalAccountingDateBase(instance()) }
        bind() from singleton { AddSpendRepository(instance()) }
        // 示例:添加另一个仓库依赖
        bind() from singleton { StatisticsRepository(instance()) }

        // 为AddSpendViewModel绑定通用工厂
        bind<ViewModelProvider.Factory>() with provider {
            GenericViewModelFactory { AddSpendViewModel(instance<AddSpendRepository>()) }
        }

        // 为StatisticsViewModel绑定通用工厂,通过命名区分不同工厂
        bind<ViewModelProvider.Factory>("StatisticsViewModelFactory") with provider {
            GenericViewModelFactory { StatisticsViewModel(instance<StatisticsRepository>()) }
        }
    }
}

3. 在页面中获取对应的ViewModel

  • 对于默认绑定的ViewModel(如AddSpendViewModel),直接通过viewModel()委托获取:
class AddSpendActivity : AppCompatActivity(), KodeinAware {
    override val kodein by closestKodein()
    private val viewModel: AddSpendViewModel by viewModel()

    // 页面逻辑代码
}
  • 对于带命名的工厂(如StatisticsViewModel),指定工厂名称即可:
class StatisticsActivity : AppCompatActivity(), KodeinAware {
    override val kodein by closestKodein()
    private val viewModel: StatisticsViewModel by viewModel(factoryName = "StatisticsViewModelFactory")

    // 页面逻辑代码
}

这种方式既满足了集中编写Application代码的需求,又避免了大量重复的ViewModelFactory类,同时保持了Kodein依赖注入的灵活性。

内容的提问来源于stack exchange,提问作者M.Shaker Nayyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:09:24