【问题标题】:Dagger Hilt - How do I inject the ViewModel into the Adapter?Dagger Hilt - 如何将 ViewModel 注入适配器?
【发布时间】:2020-10-19 13:20:56
【问题描述】:

我正在尝试将 ViewModel 注入适配器。它在注入 Fragment 时工作正常。

视图模型:

class HomeViewModel @ViewModelInject constructor(
): ViewModel() 

片段:

@AndroidEntryPoint
class HomeFragment : BaseFragment<FragmentHomeBinding, HomeViewModel>(
R.layout.fragment_home
) {

private val viewModel: HomeViewModel by viewModels()

目前没有问题。但是当我尝试注入适配器时会出现问题。

class HomeListAdapter @Inject constructor(
): BaseListAdapter<Users>(
itemsSame = { old, new -> old.username == new.username },
contentsSame = { old, new -> old == new }
) {



private val viewModel: HomeViewModel by viewModels() //viewModels() unresolved reference

更新:

如果我尝试使用构造函数注入或字段注入,我会收到以下错误:

  error: [Dagger/MissingBinding] ***.home.HomeViewModel cannot be       provided without an @Inject constructor or an @Provides-annotated method.
  public abstract static class ApplicationC implements App_GeneratedInjector,
                         ^
      ***.home.HomeViewModel is injected at
          ***.home.adapter.HomeListAdapter.viewModel
      ***.home.adapter.HomeListAdapter is injected at
          ***.home.HomeFragment.viewAdapter
      ***.home.HomeFragment is injected at
                     ***.home.HomeFragment_GeneratedInjector.injectHomeFragment(***.home.HomeFragment) [***.App_HiltComponents.ApplicationC →    ***.App_HiltComponents.ActivityRetainedC → ***.App_HiltComponents.ActivityC → ***.App_HiltComponents.FragmentC]

适配器:

class HomeListAdapter @Inject constructor(
): BaseListAdapter<Users>(
itemsSame = { old, new -> old.username == new.username },
contentsSame = { old, new -> old == new }
) {


@Inject lateinit var viewModel: HomeViewModel;

【问题讨论】:

  • 你不能这样做,因为viewModels是Fragment的扩展功能。但是,您可以通过构造函数注入或字段注入来注入视图模型。
  • 你能检查我的更新吗?如果我按照你说的做,我仍然会出错。 @Diniz
  • 请问您为什么要将视图模型注入适配器?也许您应该将您的工作委托给片段,片段本身将其委托给视图模型。不打算将视图模型注入适配器

标签: android kotlin viewmodel dagger dagger-hilt


【解决方案1】:

一般来说,你不应该将 ViewModel 注入到 Adapter,因为 Adapter 是 presentation 层的一部分,是 Android 特有的东西。 ViewModel 通常独立于 Android,尽管来自 AAC 的 ViewModel 与之相关。

您应该在 ViewModel 中获取数据并通过 LiveData 将其传递给 Fragment,然后从 Fragment 中填充您的适配器。

by viewModels() 没有在 Adapter 中定义,因为它是 Fragment 的扩展函数,只能在 Fragment 中使用。因此,将您的 ViewModel 从 Adapter 移回 Fragment。这也将修复您的编译错误,因为 Hilt 不会注入适配器。

【讨论】:

  • 您可以使用@EntryPoint 注入适配器,但顺便说一句,这是一个额外的复杂性。
【解决方案2】:

Selam Murat,如果你想通过 viewModels() 委托创建 ViewModel,你必须添加 Kotlin 片段依赖。

implementation 'androidx.activity:activity-ktx:1.1.0'
implementation 'androidx.fragment:fragment-ktx:1.1.0'

还在 build.gradle(Module: app) 文件中添加此编译选项,并在 buildTypes 中的 release 下方

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

除了在空构造函数之前不使用@Inject 或@ViewModelInject 注解。

这是为了您的更新: 也许你在尝试构造函数注入时忘记添加 @Provides 注释。

【讨论】:

  • Merhaba Enes,我已经添加了这些。但它没有用。你能给我看一个@Provides 的例子吗?
  • 这是不正确的。将@ViewModelInject 用于视图模型没有任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
相关资源
最近更新 更多