我做了一个学习Dagger的简单项目。该应用程序从Internet获取属性列表(度假租赁)并将其显示在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)
答案 0 :(得分:1)
在 David Medenjak 的评论之后,我意识到我没有正确使用构造函数注入,这种方法是错误的。正如 David Medenjak 建议我在适配器中为List<Property>
创建了一个setter,而不是在片段中初始化它。所以解决方案是:
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 :(得分:1)
你应该问自己:我真的需要注入适配器吗?
您希望这样做的两个原因:
1)适配器具有您要注入的依赖项。那不是你的情况,因为除了属性列表之外没有任何其他依赖项。
2)您想要从Activity / Fragment中删除创建Adapter实例的责任。
这两个问题的正确解决方案是注入一个已注入所有可注入依赖项的工厂,并提供实例创建方法。