2016-03-23 26 views

risposta

5

Così, ho scoperto che ho bisogno di aggiungere l'iniezione nel costruttore della mia visualizzazione personalizzata (in tutti loro, o fare una chiamata all'altra)

Esempio:

public class CustomTextView extends TextView { 
    @Inject 
    AnyProvider anyProvider; 

    public CustomTextView(Context context) { this(context, null); } 
    public CustomTextView(Context AttributeSet attrs) { 
     super(context, attrs); 
     Application.getComponent(context).inject(this); 
    } 
} 
+2

Stai usando il pugnale 2.11? Potete farmi vedere chi è questo: Application.getComponent (context)? Impossibile fare in modo che la mia Applicazione restituisca qualcosa tranne AndroidInjector. Grazie. – GuilhE

+0

Il tuo 'ApplicationComponent' - restituito da' applicationInjector() '- dovrebbe estendere' AndroidInjector 'quindi può essere lanciato su' ApplicationComponent'. Ho un avvertimento del compilatore che mi dice di sovrascrivere il tipo di ritorno di 'ApplicationComponent.Builder.build()' per chiarire questo. Probabilmente non è bello chiamare 'applicationInjector()' più volte in quanto creerà il componente molte volte, quindi sto memorizzando un riferimento ad esso ... non sono sicuro che sia comunque la soluzione migliore. Forse dare una risposta a una nuova domanda. – NeilS

+0

@GuilhE ... usarlo, restituisce il pugnale Componente daggerAppComponent = DaggerAppComponent.builder(). Application (this) .build(); –

3

la mia soluzione generale per questo genere di cose è questo

public class WelcomeView 
     extends LinearLayout { 
    private static final String TAG = "WelcomeView"; 

    public WelcomeView(Context context) { 
     super(context); 
     init(context); 
    } 

    public WelcomeView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(context); 
    } 

    public WelcomeView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     init(context); 
    } 

    @TargetApi(21) 
    public WelcomeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
     init(context); 
    } 

    private void init(Context context) { 
     if(!isInEditMode()) { 
      Application.getComponent(context).inject(this); 
     } 
    } 
+0

puoi usare this() per fare in modo che un costruttore chiami un altro, quindi non è necessario aggiungere init in tutti i costruttori –

+0

Vero, ma mi piace assicurarmi che venga chiamato da tutti i miei costruttori, nel caso che Android faccia qualcosa strano :) – EpicPandaForce

+0

Non si sta eliminando i metodi statici uno dei principali punti di iniezione delle dipendenze? Ma stai ancora chiamando un metodo statico qui. Nell'attività e nel frammento so come evitarlo ma per quanto riguarda le visualizzazioni? – kingston

2

UPDATE: Dalla versione 2.10 di Dagger questa risposta non è valida.

Vista personalizzata:

public class CustomView extends View { 
    @Inject 
    AnyObject anyObject; 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    protected void onFinishInflate() { 
     super.onFinishInflate(); 
     MainActivity mainActivity = (MainActivity) getContext(); 
     mainActivity.getComponent().inject(CustomView.this); 
    } 
} 

attività:

ActivityComponent mComponent; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mComponent = DaggerActivityComponent.builder() 
        .appComponent(getApp().getAppComponent()) 
        .activityModule(new ActivityModule(MainActivity.this)) 
        .build(); 
    mComponent.inject(MainActivity.this); 
    ... 
} 

public ActivityComponent getComponent() { 
    return mComponent; 
} 

componente Dagger2 con ambito di attività:

@ActivityScope 
@Component(dependencies = AppComponent.class, modules = {ActivityModule.class}) 
public interface ActivityComponent extends AppComponent { 

    void inject(MainActivity mainActivity); 
    void inject(CustomView customView); 
} 

Ambito:

@Scope 
@Retention(RetentionPolicy.RUNTIME) 
public @interface ActivityScope {} 
+0

.activityModule (nuovo ActivityModule (MainActivity.this)) questo è stato sottratto ora –

+1

@TusharPandey Sì, è stato ritirato dalla versione 2.10 di Dagger 2. Devo aggiornare la mia risposta al più presto. – Mussa