如何正确使用Dagger 2从适配器回调到activity / fragment?

时间:2017-09-10 15:39:36

标签: android dagger-2

我说的是上一次Google IO上显示的new architecture

现在我有了下一个实现:

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);
    }
}

MyFragment:

@Inject
ThumbnailsAdapter thumbnailsAdapter;


// 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,但它inject是理想的,但我不能(至少我不知道怎么做)正确)。我想ViewModel只是用另一个范围创建的。我试着在下一堂课中创建它:

@Module
public class ActivityModuleScopeMain {

    @Provides
    List<Thumbnail> provideThumbnails() {
        List<Thumbnail> thumbnails = new ArrayList<>();
        // here the list for adapter is created
        return thumbnails;
    }
}

另一个匕首模块展示整个(我希望)图片:

@Module
public abstract class ActivityModuleMain {

    @ContributesAndroidInjector(modules = ActivityModuleScopeMain.class)
    abstract MainFragment contributeMainFragment();
}

如果还不够,我准备发布更多代码了。

这是有效的解决方案,但我并不满意。

0 个答案:

没有答案