AnZ
AnZ

Reputation: 1060

Dagger 2 - Pass FragmentManager to constructor

I'm studying the Dagger 2 library and faced a problem of passing parameters which could not be obtained from "extends Application" class.

For example, I need to pass FragmentManager to ViewPager adapter constructor. How would you do that?

MyApplication:

public class MyApplication extends Application {

private MyAppComponent mMyAppComponent;

@Override
public void onCreate() {
    super.onCreate();

    Context context = getApplicationContext();

    mMyAppComponent= DaggerMyAppComponent.builder()
            .utilityModule(new UtilityModule())
            .locationModule(new LocationModule(context))
            .appModule(new AppModule(context))
            .pagerAdapterModule(new PagerAdapterModule(context)) //this one is problematic
            .build();
}

public MyAppComponent getmMyAppComponent() {
    return mMyAppComponent;
    }
}

MyAppComponent:

@Singleton
@Component(
    modules = {
            UtilityModule.class,
            LocationModule.class,
            PagerAdapterModule.class,
            AppModule.class
    }

)

public interface MyComponent {
    FragmentManager fragmentManager(); //is it right?

    public void inject(NavigationActivity navigationActivity);
}

AppModule:

@Module
public class AppModule {
Context context;

public AppModule(Context context) {
    this.context = context;
}

@Provides
@Singleton
Context provideApplicationContext() {
    return context;
    }
}

PagerAdapterModule:

@Module
public class PagerAdapterModule {
Context context;

public PagerAdapterModule(Context context) {
    this.context = context;
}

@Provides
@Singleton TabsPagerAdapter provideTabsPagerAdapter(FragmentManager fragmentManager) {
    return new TabsPagerAdapter(context, fragmentManager);
    }
}

NavigationActivity:

@Inject TabsPagerAdapter mTabsAdapter; //I want this to be initialized 

Upvotes: 3

Views: 4015

Answers (3)

Marjan Davodinejad
Marjan Davodinejad

Reputation: 509

i have this constructor for viewPagerAdapter and fragment that injected

@Inject
DashboardFragment dashboardFragment;

@Inject
public HomeViewPageAdapter(FragmentManager fragmentManager) {
    super(fragmentManager , BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    MyApplication.component.inject(this);
}

and create this module

        @Module
public class HomeActivityModule {

    @Provides
    HomeViewPageAdapter provideHomeViewPageAdapter(HomeActivity homeActivity) {
        return new HomeViewPageAdapter(homeActivity.getSupportFragmentManager());
    }
}

and provide HomeActivity

        @Module
public class HomeActivityModule {

    @Provides
    HomeViewPageAdapter provideHomeViewPageAdapter(HomeActivity homeActivity) {
        return new HomeViewPageAdapter(homeActivity.getSupportFragmentManager());
    }
}

finally in HomeActivity can inject viewPagerAdapter like this

@Inject
HomeViewPageAdapter homeViewPageAdapter;

Upvotes: 0

azizbekian
azizbekian

Reputation: 62189

You need to have a FragmentActivity to get a FragmentManager, which means you cannot accomplish it in Application level, because it's too soon. So you have to create a component dependency from AppComponent, let's name it ActivityComponent, which will see all dependencies that AppComponent provides.

@Component(modules = ActivityModule.class, dependencies = MyAppComponent.class)
public interface ActivityComponent {
    void inject(MainActivity mainActivity);
}

@Module
public class ActivityModule {

    FragmentActivity activity;

    public ActivityModule(FragmentActivity activity) {
        this.activity = activity;
    }

    @Provides
    TabsPagerAdapter provideTabsPagerAdapter() {
        return new TabsPagerAdapter(activity, activity.getSupportFragmentManager());
    }
}

Now in onCreate() of your activity:

public class MainActivity extends AppCompatActivity {

    @Inject
    TabsPagerAdapter tabsPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActivityComponent activityComponent = DaggerActivityComponent.builder()
                                                .activityModule(new ActivityModule(this))
                                                .myAppComponent(MyApplication.getMyAppComponent())
                                                .build();

        activityComponent.inject(this);
    }

}

Upvotes: 13

marp
marp

Reputation: 474

You can pass the FragmentManager to the PagerAdapterModule:

Context context;
FragmentManager fragmentManager;

public PagerAdapterModule(Context context, FragmentManager fragmentManager) {
    this.context = context;
    this.fragmentManager = fragmentManager;
}

Upvotes: -3

Related Questions