Сделал простой проект по изучению Dagger. Приложение извлекает из Интернета список объектов недвижимости (аренда на время отпуска) и отображает их в списке RecyclerView. Я ввел все зависимости с помощью Dagger 2, кроме адаптера для списка. Адаптер довольно стандартный, он берет список свойств и заполняет представления:
public class PropertyListAdapter extends RecyclerView.Adapter<PropertyListAdapter.ViewHolder> {
private List<Property> mPropertyList;
@Inject
public PropertyListAdapter(List<Property> propertyList) {
mPropertyList = propertyList;
}
// onCreateViewHolder()
// onBindViewHolder()
// getItemCount()
// class ViewHolder{}
}
Приложение состоит из одного действия, содержащего фрагмент, содержащий список recyclerview. В onActivityCreated() фрагмента у меня есть:
mPropertyViewModel.getPropertyList().observe(this, properties -> setPropertyAdapter(properties));
а setPropertyAdapter() - это:
private void setPropertyAdapter(List<Property> properties) {
rvPropertyList.setAdapter(new PropertyListAdapter(properties));
}
Итак, чтобы внедрить PropertyListAdapter, я создал модуль:
@Module
public class AdapterModule {
@Provides
@Singleton
PropertyListAdapter providePropertyListAdapter(List<Property> propertyList) {
return new PropertyListAdapter(propertyList);
}
}
но потом я понял, что мне нужно ввести List<Property>, и я не знаю, как этого добиться, и я застрял. Как вставить адаптер в этом примере?
P.S. Я использую MVVM с компонентами архитектуры.
Logcat: error: [dagger.android.AndroidInjector.inject(T)] java.util.List<com.aandritchi.android.propertyrentals.data.domain.Property> cannot be provided without an @Provides-annotated method.
java.util.List<com.aandritchi.android.propertyrentals.data.domain.Property> is injected at
com.aandritchi.android.propertyrentals.di.module.data.AdapterModule.providePropertyListAdapter(propertyList)
com.aandritchi.android.propertyrentals.ui.search_result.PropertyListAdapter is injected at
com.aandritchi.android.propertyrentals.ui.search_result.PropertySearchResultFragment.mPropertyListAdapter
com.aandritchi.android.propertyrentals.ui.search_result.PropertySearchResultFragment is injected at
com.aandritchi.android.propertyrentals.ui.home.HomeActivity.mPropertySearchResultFragment
com.aandritchi.android.propertyrentals.ui.home.HomeActivity is injected at
dagger.android.AndroidInjector.inject(arg0)
Да, я закачал все классы кроме адаптера.
Возможно, лучше было бы нет внедрить список, но изменить его только с помощью установщика. В противном случае вам нужно добавить метод @Provides для этого в свой модуль, см. Также здесь. И посмотрите, пожалуйста, на Внедрение конструктора, например здесь stackoverflow.com/a/50209578/1837367




После комментария Дэвид Меденьяк я понял, что я неправильно использую инъекцию конструктора, и подход был неправильным. Как подсказал Дэвид Меденьяк, я создал сеттер для List<Property> в адаптере, а затем инициализировал его во фрагменте. Итак, решение:
public class PropertyListAdapter extends RecyclerView.Adapter<PropertyListAdapter.ViewHolder> {
private List<Property> mPropertyList;
public void setPropertyList(List<Property> propertyList) {
mPropertyList = propertyList;
}
@Inject
public PropertyListAdapter() {
}
// onCreateViewHolder()
// onBindViewHolder()
// getItemCount()
// class ViewHolder{}
}
а во фрагменте мне нужно было установить список свойств:
private void setPropertyAdapter(List<Property> properties) {
mPropertyListAdapter.setPropertyList(properties); // added this line
rvPropertyList.setAdapter(mPropertyListAdapter);
}
Вы должны спросить себя: действительно ли мне нужно вводить адаптер?
Две причины, по которым вы захотите это сделать:
1) У адаптера есть зависимости, которые вы хотите ввести. Это не ваш случай, потому что нет никаких других зависимостей, кроме списка свойств.
2) Вы хотите снять ответственность за создание экземпляра адаптера из вашей активности / фрагмента.
Правильным решением обеих проблем является внедрение фабрики, в которую уже внедрены все вводимые зависимости, и которая предоставляет метод для создания экземпляра.
Также вас может заинтересовать этот вопрос: stackoverflow.com/questions/22799407/…
пожалуйста, разместите здесь свой логарифм, и можете ли вы вводить другие классы?