Внедрить в адаптер привязки данных с помощью Dagger 2 - PullRequest
0 голосов
/ 10 февраля 2019

Я использую адаптер Android Databinding, и он говорит, что он должен быть статическим.Поэтому я пытаюсь сделать его нестатичным и добавить в него свои классы с помощью Dagger, следуя этому уроку .Хотя я могу использовать свой экземпляр Picasso, который обычно предоставляется в приложении кинжалом, он говорит: Picasso cannot be provided without an @Inject constructor or an @Provides-annotated method.

Я добавляю аннотацию @Inject в конструктор адаптера привязки, но все равно получаю ту же ошибку

public class ImageBindingAdapter {

    private final Picasso picasso;

    @Inject
    public ImageBindingAdapter(Picasso picasso) {
        this.picasso = picasso;
    }

    @BindingAdapter("android:src")
    public void loadImage(ImageView view, String url) {
        picasso.load(url).fit().into(view);
    }
}

Я подумал, что проблема может иметь отношение к проблеме component, и изменил мой подход и следовал по этой ссылке и использовал subcomponent.Но на этот раз кинжал не может генерировать подкомпонент, и я не могу установить его, как в примере

// Build dagger binding subcomponent and set it like default databinding component 
        DataBindingUtil.setDefaultComponent(sApplicationComponent
                .daggerBindingComponentBuilder()
                .build());

Как я могу внедрить свои пользовательские классы в связывающий адаптер с Dagger, любая помощь приветствуется

Вот мои классы кинжалов, это то же самое из учебника, о котором я упоминал выше

Класс ImageBindingAdapter

public class ImageBindingAdapter {

    private final Picasso picasso;

    @Inject
    public ImageBindingAdapter(Picasso picasso) {
        this.picasso = picasso;
    }

    @BindingAdapter("android:src")
    public void loadImage(ImageView view, String url) {
        picasso.load(url).fit().into(view);
    }
}

Класс BindingModule

@Module
public class BindingModule {

    @Provides 
    @DataBinding
    ImageBindingAdapter provideImageBindingAdapter(Picasso picasso) {
        return new ImageBindingAdapter(picasso);
    }
}

Класс BindingComponent

@DataBinding
@Component(dependencies = AppComponent.class, modules = BindingModule.class)
public interface BindingComponent extends DataBindingComponent {

}

Класс AppComponent

@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, ...})
public interface AppComponent extends AndroidInjector<MyApp> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder application(Application application);
        AppComponent build();

    }

    @Override
    void inject(MyApp instance);
}

Класс AppModule

@Module
public class AppModule {

    @Singleton
    @Provides
    Picasso picasso(Application application, OkHttp3Downloader okHttp3Downloader) {
        return new Picasso.Builder(app.getApplicationContext())
                .downloader(okHttp3Downloader)
                .indicatorsEnabled(true)
                .build();
    }

     ....

}

Класс применения

    public class MyApp extends DaggerApplication {

        @Override
        protected AndroidInjector<MyApp> applicationInjector() {

           AppComponent appComponent = DaggerAppComponent.builder().application(this).build();

            appComponent.inject(this);

            BindingComponent bindingComponent = DaggerBindingComponent.builder()
                .appComponent(appComponent)
                .build();
             DataBindingUtil.setDefaultComponent(bindingComponent);

            return appComponent;
        }
    }

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

@ BindingAdapter должен быть public static void, см. Документы по привязке адаптеров .

0 голосов
/ 11 февраля 2019

Как сказано в сообщении об ошибке, кинжал не может разрешить зависимость Picasso.В вашем случае проблема заключается в том, что разные компоненты кинжала могут напрямую использовать только те зависимости, интерфейс которых помечен аннотацией @Component, объявленной с использованием методов.Чтобы разрешить AppComponent поделиться Picasso с BindingComponent, вам нужно изменить компонент приложения следующим образом:

@Singleton 
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, ...}) 
public interface AppComponent extends AndroidInjector<MyApp> { 
    ...
    Picasso getPicasso();
}

После этого кинжал сможет правильно разрешить Picasso зависимость, и ошибка должна исчезнуть.

...