Как правильно использовать Dagger 2 для прокидывания callback из adapter в activity/fragment?

Оговорю сразу, речь идет о новой архитектуре, представленной на последнем Google IO.

В данный момент, у меня получилась такая реализация:

public class ThumbnailsAdapterViewModel extends ViewModel {

    MutableLiveData<ThumbnailSelected> thumbnailSelectedMutableLiveData = new MutableLiveData<>();

    @Inject
    public ThumbnailsAdapterViewModel() {
    }

    public LiveData<ThumbnailSelected> getSelectedThumbnail() {
        return thumbnailSelectedMutableLiveData;
    }

    public void setThumbnailSelected(ThumbnailSelected thumbnailSelected) {
        thumbnailSelectedMutableLiveData.setValue(thumbnailSelected);
    }
}


Fragment, член класса:
@Inject
ThumbnailsAdapter thumbnailsAdapter;


Fragment, onCreateView:
ThumbnailsAdapterViewModel thumbnailsAdapterViewModel = ViewModelProviders.of(this, viewModelFactory).get(ThumbnailsAdapterViewModel.class);
        thumbnailsAdapterViewModel.getSelectedThumbnail().observe(this, new Observer<ThumbnailSelected>() {
            @Override
            public void onChanged(@Nullable ThumbnailSelected thumbnailSelected) {
                if (thumbnailSelected != null) {
                    Snackbar.make(getView(), "Thumbnail #" + thumbnailSelected.getPosition() + " is selected", Snackbar.LENGTH_SHORT).show();
                }
            }
        });

thumbnailsAdapter.setViewModel(thumbnailsAdapterViewModel);


ThumbnailsAdapter:
public class ThumbnailsAdapter extends RecyclerView.Adapter<ThumbnailsAdapter.ViewHolder> {

    List<Thumbnail> thumbnails;
    private ThumbnailsAdapterViewModel viewModel;

    @Inject
    public ThumbnailsAdapter(List<Thumbnail> thumbnails) {
        this.thumbnails = thumbnails;
    }

    public void setViewModel(ThumbnailsAdapterViewModel viewModel) {
        this.viewModel = viewModel;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_thumbnail, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.bindData(thumbnails.get(position), position);
    }

    @Override
    public int getItemCount() {
        return thumbnails.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
         // ... implementation

    public void bindData(final Thumbnail thumbnail, final int position) {
           
            imageThumbnail.setImageResource(R.drawable.ic_thumbnail);
          
            imageThumbnail.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    viewModel.setThumbnailSelected(new ThumbnailSelected(thumbnail, position));
                }
            });
        }
    }
}


Главный минус: я явно передаю ViewModel в Adapter, а заинджектить ее не могу, потому что если этим занимается даггер, то модель создается с другим scope (это мое предположение, я в даггере новичек).

Еще пару классов даггера:

@Module
public class ActivityModuleScopeMain {

    @Provides
    List<Thumbnail> provideThumbnails() {
        List<Thumbnail> thumbnails = new ArrayList<>();
        // тут создается список
        return thumbnails;
    }
}


@Module
public abstract class ActivityModuleMain {

    @ContributesAndroidInjector(modules = ActivityModuleScopeMain.class)
    abstract MainFragment contributeMainFragment();
}
  • Вопрос задан
  • 610 просмотров
Решения вопроса 1
@rocknow Автор вопроса
Покопался в примере, там нашел адаптер.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы