1

I have a MainActivity, and There is a nested MainFragment in my MainActivity, and even more, There are a list of ChildFragment in the MainFragment.Every Activity or Fragment has a Module and Subcomponent. Now I want to inject the list of ChildFragment int the MainFragment, but If I use the List<Fragment> provided method with the @FragmentScoped annotation in the MainFragmentModule, it will cause an error which said the fragment list cannot be provided without an @Provides-annotated method. Instead if I put the List<Fragment> provided method in the MainActivityModule with annotation @ActivityScoped, it works.Could anyone tell me that's why? Here is the code:

MainActivityModule :

@Module
public abstract class MainActivityModule {
    @ContributesAndroidInjector(modules = {MainFragmentModule.class})
    @FragmentScoped
    abstract MainFragment mainFragment();
}

MainFragmentModule :

@Module
public abstract class MainFragmentModule {

    @ContributesAndroidInjector(modules = {HomeModule.class})
    @ChildFragmentScoped
    abstract HomeFragment homeFragment();

    @ContributesAndroidInjector
    @ChildFragmentScoped
    abstract NewsFragment newsFragment();

    @ContributesAndroidInjector
    @ChildFragmentScoped
    abstract MomentsFragment momentsFragment();

    @ContributesAndroidInjector
    @ChildFragmentScoped
    abstract WalletFragment walletFragment();

    @ContributesAndroidInjector
    @ChildFragmentScoped
    abstract PersonalFragment personalFragment();

    @FragmentScoped
    @Provides
    static List<Fragment> provideList(HomeFragment home, NewsFragment news, MomentsFragment moments, WalletFragment wallet, PersonalFragment personal) {
        List<Fragment> fragments = new ArrayList<>();
        fragments.add(home);
        fragments.add(news);
        fragments.add(moments);
        fragments.add(wallet);
        fragments.add(personal);
        return fragments;
    }
}

FragmentAdapter:

public class FragmentAdapter extends PagerAdapter {

    //...

    @Inject
    public FragmentAdapter(List<Fragment> fragments, FragmentUtil fragmentUtil) {
        mFragments = fragments;
        mFragmentUtil = fragmentUtil;
    }

    //...

}

MainFragment:

public class MainFragment extends DaggerFragment{

    //...

    @Inject
    FragmentAdapter mFragmentAdapter;

    @Inject
    public MainFragment() {
        // Required empty public constructor
    }

    //...
}

If I use the List<Fragment> provided method with the @FragmentScoped annotation in the MainFragmentModule, it will cause the following error:

Error:(20, 8) Error: [dagger.android.AndroidInjector.inject(T)]  java.util.List<android.support.v4.app.Fragment> cannot be provided without an @Provides-annotated method.
java.util.List<android.support.v4.app.Fragment> is injected at
com.sample.fragment.FragmentAdapter.<init>(fragments, …)
com.sample.fragment.FragmentAdapter is injected at
com.sample.fragment.MainFragment.mFragmentAdapter
com.sample.fragment.MainFragment is injected at
com.sample.activity.MainActivity.mMainFragment
com.sample.activity.MainActivity is injected at
dagger.android.AndroidInjector.inject(arg0)

But with the following code it works:

@Module
public abstract class MainActivityModule {

    @ActivityScoped
    @Provides
    static List<Fragment> provideList(HomeFragment home, NewsFragment news, MomentsFragment moments, WalletFragment wallet, PersonalFragment personal) {
        List<Fragment> fragments = new ArrayList<>();
        fragments.add(home);
        fragments.add(news);
        fragments.add(moments);
        fragments.add(wallet);
        fragments.add(personal);
        return fragments;
    }
}
KevinYe
  • 61
  • 4
  • Please include the full error in your question. Also, please see and read here: https://stackoverflow.com/q/44912080/1837367 – David Medenjak Jan 23 '18 at 11:52

1 Answers1

0

Well, It seems that I have found the problem. When I inject the MainFragment in my MainActivity, because the MainFragment has an @Inject member which is FragmentAdapter, it needs to inject the FragmentAdapter . By the same way, it needs List injected. However, I provide the List in the MainFragmentModule, the parent subcomponent cannot use the provided dependencies of its child subcomponent.

KevinYe
  • 61
  • 4