2017-06-09 5 views
1

Ich versuche, meine MainActivity in das Fragment zu injizieren. Ich habe eine Schnittstelle, die in meiner MainActivity implementiert ist, die Ereignisse von dem Fragment anhören wird. Also möchte ich die MainActivity injizieren und den Event-Listener darauf aufrufen.So injizieren Sie eine Aktivität in ein Fragment mit Dagger2

Ich habe versucht, Folgendes zu tun, hat es aber versäumt, dies zu tun. Nur die Code-Schnipsel anzeigen.

Schnittstelle

public interface RecipeItemListener { 
    void onRecipeItem(); 
} 

MainActivity, die die Schnittstelle implementiert

public class MainActivity extends AppCompatActivity implements RecipeItemListener { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     if(savedInstanceState == null) { 
      getSupportFragmentManager() 
        .beginTransaction() 
        .add(R.id.main_fragment_container, RecipeListView.newInstance(), RecipeListView.TAG) 
        .commit(); 
     } 
    } 

    @Override 
    public void onRecipeItem() { 
     Timber.d("onRecipeItem"); 
    } 
} 

Mein Modul, das die MainActivity

@Module 
public class RecipeListModule { 
    private MainActivity mainActivity; 

    public RecipeListModule(MainActivity mainActivity) { 
     this.mainActivity = mainActivity; 
    } 

    @RecipeListScope 
    @Provides 
    public RecipeItemListener providesRecipeListMainActivity() { 
     return mainActivity; 
    } 
} 

Meine Hauptkomponente bietet
@Singleton 
@Component(modules = { 
     AndroidModule.class, 
     NetworkModule.class}) 
public interface BusbyBakingComponent { 
    RecipeListComponent add(RecipeListModule recipeListModule); 
} 

Meine Unterkomponente

@RecipeListScope 
@Subcomponent(modules = {RecipeListModule.class}) 
public interface RecipeListComponent { 
    void inject(RecipeListView target); 
} 

Meine Anwendungsklasse

public class BusbyBakingApplication extends Application { 
    private BusbyBakingComponent applicationComponent; 
    private RecipeListComponent recipeListComponent; 

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

     applicationComponent = createApplicationComponent(); 
    } 

    public BusbyBakingComponent createApplicationComponent() { 
     return DaggerBusbyBakingComponent.builder() 
       .networkModule(new NetworkModule()) 
       .androidModule(new AndroidModule(BusbyBakingApplication.this)) 
       .build(); 
    } 

    public BusbyBakingComponent getApplicationComponent() { 
     return applicationComponent; 
    } 

    public RecipeListComponent createRecipeListComponent(MainActivity activity) { 
     recipeListComponent = applicationComponent.add(new RecipeListModule(activity)); 
     return recipeListComponent; 
    } 

    public void releaseRecipeListComponent() { 
     recipeListComponent = null; 
    } 
} 

und in meinem Fragmente das ist, wie ich zu injizieren versuchen:

@Inject MainActivity mainActivity; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ((BusbyBakingApplication)getActivity().getApplication()) 
      .createRecipeListComponent((MainActivity)getActivity()) 
      .inject(RecipeListView.this); 
} 

Ich halte die folgende Fehlermeldung erhalten:

Error:(14, 8) error: [me.androidbox.busbybaking.di.RecipeListComponent.inject(me.androidbox.busbybaking.recipieslist.RecipeListView)] me.androidbox.busbybaking.recipieslist.MainActivity cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method. 
me.androidbox.busbybaking.recipieslist.MainActivity is injected at 
me.androidbox.busbybaking.recipieslist.RecipeListView.mainActivity 
me.androidbox.busbybaking.recipieslist.RecipeListView is injected at 
me.androidbox.busbybaking.di.RecipeListComponent.inject(target) 

Vielen Dank für Anregungen.

+2

Erhalten Sie die Aktivität im Fragment nicht bereits mit 'getActivity()'? – EpicPandaForce

Antwort

1

Wenn Sie einen Blick auf Ihrem Modul haben

@RecipeListScope 
@Provides 
public RecipeItemListener providesRecipeListMainActivity() { 
    return mainActivity; 
} 

Sie stellen die Schnittstelle (die gut ist) und nicht MainActivity (die Implementierung).

Da Sie MainActivity

@Inject MainActivity mainActivity; 

anfordern erhalten Sie diesen Fehler:

MainActivity cannot be provided [...]

, weil Sie nur RecipeItemListener bieten.


Code Schalten von erfordern MainActivity in RecipeListView zu

@Inject RecipeItemListener recipeListener; 

und es sollte funktionieren, wenn der Rest der Einrichtung korrekt ist.

+0

dieser Fix arbeitete. Der Grund, warum ich injizieren wollte, wie ich die Methode in der MainActivity aufrufen möchte, die die Schnittstelle von dem Fragment implementiert, das von der Aktivität gehostet wird. Ich denke, ich hätte die Aktivität an das Fragment in der onAttach-Methode übergeben können. Aber ich dachte, dass injizieren der bessere Weg ist. – ant2009

0

Sie Aktivität in Fragmente mit getActivity Zugriff() und wirft ihn auf Ihre Schnittstelle Zuhörer wie diese

((RecipeItemListener)getActivity()).doSomethingOnListener() 

viel einfacher, ohne unnötige Injektionen

Verwandte Themen