【问题标题】:Inject Adapter to Fragment using Dagger2使用 Dagger2 将适配器注入片段
【发布时间】:2019-02-20 19:50:59
【问题描述】:

我已按照 Android Architecture Blueprints Dagger2 进行依赖注入:https://github.com/googlesamples/android-architecture/tree/todo-mvp-dagger

现在我想将 Adapter 注入我的 Fragment 类:

@ActivityScoped
class MainFragment @Inject
constructor(): DaggerFragment() {

    @Inject lateinit var adapter : ArtistAdapter 
}

我在模块类中有以下内容:

@Module
abstract class MainModule {
    @FragmentScoped
    @ContributesAndroidInjector
    internal abstract fun mainFragment(): MainFragment

    @Module
    companion object {
        @Provides
        @ActivityScoped
        @JvmStatic internal fun provideArtistAdapter() = ArtistAdapter()
    }
}

但由于某种原因,它无法在 RecyclerView 中显示数据。当我不使用注入并仅使用val adapter = ArtistAdapter() 时,它可以工作。

我在使用 Dagger2 进行注入时遗漏了什么?

附录:

mainFragment 正在实现一个回调作为点击监听器:

interface ArtistClickCallback {
    fun onClick(artist: LastFmArtist, poster : ImageView)
}

还有:

class MainFragment : DaggerFragment(), ArtistClickCallback

这里是片段模块:

@Module
class MainFragmentModule {

    @Provides
    fun provideArtistAdapter(mainFragment: MainFragment) = ArtistAdapter(mainFragment)

}

但是当我从 Fragment 构造函数中删除 @Inject 时出现以下异常:

error: [Dagger/MissingBinding] com.sample.android.lastfm.ui.main.MainFragment cannot be provided without an @Inject constructor or an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.sample.android.lastfm.LastFmApp> {
                ^
  A binding with matching key exists in component: com.sample.android.lastfm.ui.main.MainModule_MainFragment$app_debug.MainFragmentSubcomponent
      com.sample.android.lastfm.ui.main.MainFragment is injected at
          com.sample.android.lastfm.ui.main.MainActivity.mainFragment
      com.sample.android.lastfm.ui.main.MainActivity is injected at
          dagger.android.AndroidInjector.inject(T) [com.sample.android.lastfm.di.AppComponent → com.sample.android.lastfm.di.ActivityBindingModule_MainActivity$app_debug.MainActivitySubcomponent]

【问题讨论】:

  • 1.您不应该在 Fragment 的构造函数中使用 @Inject 注释。 2. 您应该在 MainFragment 和伴随对象中使用相同的范围 - FragmentScoped。 3. 在片段的 onAttach 或 onCreate 中,你应该调用 DaggerFragmentComponent.inject(fragment)。
  • 查看谷歌示例,他们在构造函数中使用了@inject 注释:github.com/googlesamples/android-architecture/blob/…
  • 有什么特别的原因要注入适配器吗?它有什么实际好处吗?我以前看过,但我不确定它是否值得。
  • @EpicPandaForce 不,没有特别的原因。我只是问了学习的目的。

标签: android kotlin android-recyclerview dagger-2


【解决方案1】:

从 Fragment 构造函数中删除 @Inject 并向片段提供适配器或在适配器中使用注入构造函数

@Module
abstract class MainModule {
    @FragmentScoped
    @ContributesAndroidInjector(modules = [MyAwesomeFragmentModule::class])
    internal abstract fun mainFragment(): MainFragment

} 

-

@Module
class MyAwesomeFragmentModule {

    @Provides
    fun provideArtistAdapter() = ArtistAdapter()

}

【讨论】:

  • 谢谢@Ismael Di Vita。我在构建时收到异常。请查看我的问题中的addenda 部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多