【问题标题】:Android Dagger get Parent Fragment into child fragmentAndroid Dagger 将父片段转换为子片段
【发布时间】:2018-08-27 01:47:31
【问题描述】:

我一直试图将父片段注入其子片段以进行导航,但未成功。我关注了几个不同的帖子,但我似乎无法理解我在实现中缺少什么。

我有一个MainActivity,其中包含一个ViewPager,其中一个页面包含EventsFragment。该片段又具有两个子片段EventsListFragmentEventsDetailFragment。我想将EventsFragment 片段注入EventsListFragment,以便我可以告诉它导航到EventsDetailFragment

我知道这可能是对以下帖子的重复,对此我深表歉意,但老实说,我看不出我错过了什么。这些是我找到的帖子:

我的实现如下:

应用组件

@Singleton
@Component(modules = [
    AndroidSupportInjectionModule::class,
    ActivityModule::class,
    BaseApplicationModule::class,
    ApplicationModule::class])
interface ApplicationComponent : AndroidInjector<AndroidApplication> {

@Component.Builder
    abstract class Builder : AndroidInjector.Builder<AndroidApplication>()
}

活动模块

@Module(includes = [MainActivityProvider::class])
abstract class ActivityModule{

}

MainActivityProvider

@Module(includes = [EventsFragmentProvider::class])
abstract class MainActivityProvider {
    @PerActivity
    @ContributesAndroidInjector(modules = [MainActivityModule::class])
    abstract fun provideMainActivityFactory(): MainActivity
}

EventsFragmentProvider

@Module(includes = [EventsListProvider::class, 
EventsDetailProvider::class])
abstract class EventsFragmentProvider {
    @PerFragment
    @ContributesAndroidInjector(modules = [EventsFragmentModule::class])
    abstract fun provideEventsFragmentFactory(): EventsFragment
}

EventsFragmentModule

@Module
class EventsFragmentModule {
     @Binds
     abstract fun providesEventListView(eventsFragment: EventsFragment): EventContract.Flow
}

EventsListProvider

@Module
abstract class EventsListProvider {
    @PerFragment
    @ContributesAndroidInjector(modules = [EventsListModule::class])
    abstract fun provideEventsListFragmentFactory(): EventsListFragment
}

EventsFragment

class EventsFragment : DaggerFragment(), EventContract.Flow {
    override fun navigateToList() {
        addFragment(navigator.getEventsListFragment(context!!))
    }

    override fun navigateToDetail(id: String) {
        println("id = ${id}")
    }

    ...
}

EventContract

interface EventContract {
    interface Flow {
        fun navigateToList()

        fun navigateToDetail(id: String)
    }
}

EventsListFragment

class EventsListFragment : DaggerFragment() {
    @Inject
    lateinit var eventsFlow: EventContract.Flow

    ...

}

错误

[Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] EventContract.Flow cannot be provided without an @Provides-annotated method.
public abstract interface ApplicationComponent extends dagger.android.AndroidInjector<AndroidApplication> {
            ^
      EventContract.Flow is injected at
          EventsListFragment.eventsFlow
      EventsListFragment is injected at
          dagger.android.AndroidInjector.inject(T)
  component path: ApplicationComponent →EventsListProvider_ProvideEventsListFragmentFactory.EventsListFragmentSubcomponent

我可能使用了反模式,但这正是我工作到现在的原因。我愿意接受可能帮助我实现这一目标的更改

【问题讨论】:

  • 错误是什么?
  • 抱歉刚刚添加了错误
  • 您的 EventsListFragment 需要一个 EventContract.Flow 。因此,您必须将能够提供 EventContract.Flow (EventsFragmentModule) 的模块添加到该片段的 @ContributesAndroidInjector 模块。这就是说,我不确定它是如何工作的

标签: android android-fragments dagger-2 dagger


【解决方案1】:

错误是由以下模块引起的:

@Module
class EventsFragmentModule {
     @Binds
     abstract fun providesEventListView(eventsFragment: EventsFragment): EventContract.Flow
}

Dagger 不会为您提供Fragment,您不应该这样做。

此外,我认为您误解了@ContributesAndroidInjector 的含义。这意味着为您创建一个AndroidInjector,但要证明一个实例。

@Module
abstract class EventsListProvider {
    @PerFragment
    @ContributesAndroidInjector(modules = [EventsListModule::class])
    abstract fun provideEventsListFragmentFactory(): EventsListFragment
}

因此,您应该像 post 那样将您的 EventsFragment 实例传递到模块中,而不是使用字段注入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 1970-01-01
    相关资源
    最近更新 更多