android - 使用 Hilt 进行依赖注入时如何将运行时参数传递给 ViewModel 的构造函数?
问题描述
我想知道如何在使用 Hilt 进行 DI 时将运行时参数传递给 ViewModel 的构造函数?在使用 Hilt 之前,我有一个如下所示的 ViewModel:
class ItemViewModel(private val itemId: Long) : ViewModel() {
private val repo = ItemRepository(itemId)
}
class ItemViewModelFactory(private val itemId: Long) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ItemViewModel::class.java)) {
return ItemViewModel(itemId) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
我在我的片段中创建了上面的 ViewModel,如下所示:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val args: ItemScreenFragmentArgs by navArgs()
val itemId = args.itemId
//Create the view model factory
val viewModelFactory = ItemViewModelFactory(application, itemId)
// Get a reference to the ViewModel associated with this fragment.
val itemViewModel = ViewModelProvider(this, viewModelFactory).get(ItemViewModel::class.java)
}
如果我的 ItemViewModel 构造函数没有 itemId 参数,我使用 Hilt 的 ViewModel 和 Fragment 将如下所示:
class ItemViewModel
@ViewModelInject
constructor(private val repo: ItemRepository) : ViewModel() { }
@AndroidEntryPoint
class ItemFragment : Fragment() {
private val itemViewModel: ItemViewModel by viewModels ()
}
我试图弄清楚如何将从 ItemFragment 的 NavArgs 获得的 itemId 传递给 ItemViewModel 的构造函数?有没有办法用 Hilt 做到这一点?
解决方案
对于其他希望在使用 Dagger Hilt 时将运行时参数传递给 ViewModel 的人,我是这样做的:
我遵循了这个示例中的代码,它使用了AssistedInject库。
我的代码现在如下所示:
class ItemViewModel
@AssistedInject
constructor(private val repo: ItemRepository, @Assisted private val itemId: Long) : ViewModel() {
init {
repo.itemId = itemId
}
@AssistedInject.Factory
interface AssistedFactory {
fun create(itemId: Long): ItemViewModel
}
companion object {
fun provideFactory(
assistedFactory: AssistedFactory,
itemId: Long
): ViewModelProvider.Factory = object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return assistedFactory.create(itemId) as T
}
}
}
}
@InstallIn(FragmentComponent::class)
@AssistedModule
@Module
interface AssistedInjectModule {}
@AndroidEntryPoint
class ItemFragment : Fragment() {
private val args: ItemScreenFragmentArgs by navArgs()
@Inject lateinit var itemViewModelAssistedFactory: ItemViewModel.AssistedFactory
private val itemViewModel: ItemViewModel by viewModels {
ItemViewModel.provideFactory(itemViewModelAssistedFactory, args.itemId)
}
}
推荐阅读
- android - 在 Kotlin、Android Studio 中每天将值重置为 0?
- pytorch - PyTorch 编译器是否允许矢量化 mad() 函数?
- python - 使用带有 RS232 端口的 pymodbus 从 CLICK PLC 读取计数器值到 python
- java - Maven项目中的构建顺序
- c++ - 关于 C++ 中星号和字符串连接的问题
- java - 弹簧未初始化 - 应用程序未启动
- javascript - Javascript Do while 循环仅在一次迭代后停止
- excel - 获取从另一个页面复制的表格名称
- awk - 如何在忽略较少数量的连续行的同时将每块 3 行合并在一起?
- css - 换行 Office UI Fabric DetailsRow 的文本