Dagger used inside recycleview for MVP pattern
Updated:
The main purpose of Dependency Injection pattern which is implemented by Dagger 2 is that DI separates the creation of a client’s dependencies from the client’s behavior. In practice it means that all calls of new operator, newInstance() and others shouldn’t be invoked in places other than Dagger’s Modules.
The beginning
Imagine that you have the recycleview which has to retrive the data content from network (or disk) only when it is necessary to show the items inside itself.
Here you can see starting code base for our example. For me this is how the first iteration of implemented Adapter looks like in most cases.
NewsRecyclerViewAdapter
public class NewsRecyclerViewAdapter extends RecyclerView.Adapter
private ArrayList<String> news = new ArrayList<>();
private PublishSubject<Item> notify = PublishSubject.create();
private NewsFragment newsFragment;
@Inject
public NewsBasePresenter presenter;
@Inject
public NewsRecyclerViewAdapter(NewsFragment newsFragment) {
this.newsFragment = newsFragment;
}
public void setNews(String[] news) {
this.news = new ArrayList<>(Arrays.asList(news));
}
public void addMoreNews(String[] news) {
this.news.addAll(new ArrayList<>(Arrays.asList(news)));
}
@Override
public NewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_item, parent, false);
NewViewHolder newViewHolder = new NewViewHolder(view );
newsFragment.getDependenciesModules()
.plus(new AdapterModule(newViewHolder))
.inject(newViewHolder);
return newViewHolder;
}
@Override
public void onBindViewHolder(final NewViewHolder holder, int position) {
final String newIndex = news.get(position);
holder.presenter.fetchData(newIndex);
RxView.clicks(holder.view)
.map(aVoid -> holder.item)
.subscribe(notify::onNext);
}
public Observable<Item> asObservable() {
return notify.asObservable();
}
@Override
public int getItemCount() {
return news.size();
}
}
Explaination
Here we can see the code above, the injection happen whenever there is a new viewholder being created, which means the presenter only attached to the view holder which can always use the right view (ViewHolder) to show and save the memory assumption.
Inside AdapterModule implementation, make sure you have the presenter or any model layer being inialized to make the model and controller works.
More info: github