Search code examples
javaandroidandroid-fragmentsdagger-2dagger

Dagger 2: How to use injection with a Fragment


I'm using AndroidInjection.inject(this) to inject components into an activity.

AndroidInjection also has an overloaded method that takes android.app.Fragment as a parameter. But my fragments extend android.support.v4.app.Fragment and there is no corresponding method.

Question: How to use injection if a fragment extends android.support.v4.app.Fragment?


Solution

  • For support library fragments you need to use support injection. Here some example:

    @Singleton
    @Component(modules = {
            AndroidSupportInjectionModule.class, // Important
            ActivityModule.class,
            FragmentModule.class
    })
    
    public interface AppComponent extends AndroidInjector<App> {
    
        void inject(App app);
    
        @Component.Builder
        interface Builder {
            @BindsInstance
            Builder application(Application application);
            AppComponent build();
        }
    }
    

    Application, you can use DaggerApplication or simple HasSomeIjection if you need for example Multidex implementation:

    public class App extends MultiDexApplication implements
        HasActivityInjector,
        HasFragmentInjector {
    
        @Inject DispatchingAndroidInjector<Activity> activityInjector;
        @Inject DispatchingAndroidInjector<Fragment> fragmentInjector;
        private AppComponent mComponent;
    
        @Override
        public void onCreate() {
            mComponent = DaggerAppComponent.builder().application(this).build();
            mComponent.inject(this);
        }
    
        // Dependency Injection
        @Override
        public DispatchingAndroidInjector<Activity> activityInjector() {
            return activityInjector;
        }
    
        @Override
        public DispatchingAndroidInjector<Fragment> fragmentInjector() {
            return fragmentInjector;
        }
    }
    

    Next module:

    @Module
    public abstract class FragmentModule {
        @ContributesAndroidInjector
        abstract ContactsFragment bindContactsFragment();
    }
    

    Activity module:

    @Module
    public abstract class ActivityModule {
        @ContributesAndroidInjector
        abstract ContactsActivity bindContactsActivity();
    }
    

    And fragment:

    import com.some.ContactsPresenter;
    import dagger.android.support.DaggerFragment;
    
    public class ContactsFragment extends DaggerFragment {
    
        @Inject
        ContactsPresenter mContactsPresenter;
    
        // .....
    }
    

    If you don't want use the DaggerFragment, you can open its implementation and copied to your fragment with necessary changes. The main feature here is using AndroidSupportInjectionModule. Hope this will help you