View dependency injection with dagger 2

前端 未结 3 923
伪装坚强ぢ
伪装坚强ぢ 2021-02-09 05:09

I have a custom view extending a TextView. Where should I call my component to inject the view?

component.inject(customTextView);
相关标签:
3条回答
  • 2021-02-09 05:45

    UPDATE: Since 2.10 version of Dagger this answer is invalid.

    Custom view:

    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);
        }
    }
    

    Activity:

    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;
    }
    

    Dagger2 component with Activity scope:

    @ActivityScope
    @Component(dependencies = AppComponent.class, modules = {ActivityModule.class})
    public interface ActivityComponent extends AppComponent {
    
        void inject(MainActivity mainActivity);
        void inject(CustomView customView);
    }
    

    Scope:

    @Scope
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ActivityScope {}
    
    0 讨论(0)
  • 2021-02-09 05:54

    So, I've find out that I need to add the injection in the constructor of my custom view (in all of them, or make one call the other)

    Example:

    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);
       }
    }
    
    0 讨论(0)
  • 2021-02-09 05:59

    My general solution for that kind of thing is this

    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 讨论(0)
提交回复
热议问题