如何将活动和碎片注入RecyclerAdapter(Dagger 2)

时间:2016-10-11 08:12:19

标签: android dependency-injection dagger-2

大家!

我对Dagger2很新,但我真的很想了解它。首先,让我们看一下RecyclerAdapter的代码,我已经通过一些应用程序级注入(DbHelper和应用程序上下文)实现了。

另外,请注意,这里我们有两个DataSetChangeListener和DataProviderListener实例:

  • DataSetChangeListener - 是一个调用Fragment中某些方法的接口(管理视图);
  • DataProviderListener - 是调用Activity中的方法的接口(管理数据模型调用);

所以,这是代码:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.EmotionsViewHolder> {
    @Inject
    DbHelper mDbHelper;
    @Inject
    Context mContext;

    private ArrayList<String> mItemsList;
    private DataSetChangeListener mDataSetChangeListener;
    private DataProviderListener mDataProviderListener;

    public RecyclerAdapter(DataProviderListener dataProviderListener, DataSetChangeListener listener) {
        App.getAppComponent().inject(this);
        //TODO: Replace with dagger 2 injection
        mDataSetChangeListener = listener;
        mDataProviderListener = dataProviderListener;
        mItemsList = dataProviderListener.getDataSet();
        notifyFragmentAboutDataSetStatus();
    }

    private void notifyFragmentAboutDataSetStatus() {
        if (mItemsList.size() == 0) {
            mDataSetChangeListener.notifyDataSetIsEmpty();
        } else {
            mDataSetChangeListener.notifyDataSetIsNotEmpty();
        }
    }

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

    @Override
    public void onBindViewHolder(EmotionsViewHolder holder, final int position) {
        holder.mEmotionsTextView.setText(mItemsList.get(position));
        holder.mEditImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                editItem(position);
            }
        });
        holder.mDeleteImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                removeItem(position);
            }
        });
    }

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

    public void addItem(String item) {
        mItemsList.add(item);
        notifyItemInserted(mItemsList.size());
    }

    private void editItem(int position) {
        String currentValue = mItemsList.get(position);
        mDataProviderListener.callEditDialog(currentValue);
    }

    private void removeItem(int position) {
        String[] selectionArgs = new String[]{mItemsList.get(position)};
        mItemsList.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, mItemsList.size());

        Uri uri = UniquesContract.EmotionsEntity.CONTENT_URI;
        String selection = UniquesContract.EmotionsEntity.EMOTION_COL + " = ?";
        mContext.getContentResolver().delete(uri, selection, selectionArgs);
    }

    static class EmotionsViewHolder extends RecyclerView.ViewHolder {
        TextView mEmotionsTextView;
        ImageView mEditImageView;
        ImageView mDeleteImageView;

        public EmotionsViewHolder(View view) {
            super(view);
            mEmotionsTextView = (TextView) view.findViewById(R.id.emotion_text_view);
            mEditImageView = (ImageView) view.findViewById(R.id.edit_item_image_view);
            mDeleteImageView = (ImageView) view.findViewById(R.id.delete_item_image_view);
        }
    }

    public void setNewDataSet(ArrayList<String> list) {
        mItemsList = list;
    }


}

我意识到,理论上我可以注入 DataSetChangeListener DataProviderListener ,但我怎么能这样做。也许,关键在于创建一个新的范围?但我不知道如何使用它。如果我甚至没有能力从RecyclerAdapter类引用它们,我怎么能在RecyclerAdapter中实例化这两个对象。将实例作为构造函数的paremethers传递已经不是DI。我该怎么办?

1 个答案:

答案 0 :(得分:2)

使用更多Dagger和Dependency Injection使您的项目更改的所有更改取决于您的整个项目结构!但是,如果您想注入这两个接口,您可以为RecyclerAdapter编写一个提供程序方法,并在模块中将这些接口注入其中:

@Provides
@Singleton
public RecyclerAdapter provideRecyclerAdapter(DataProviderListener dataProviderListener, DataSetChangeListener listener) {
    return new RecyclerAdapter(dataProviderListener, listener);
}
  

请注意:另一个提供者或您的模块构造函数必须提供   这些接口在注射时。

您还可以通过将@Inject注释添加到RecyclerAdapter构造函数来执行构造函数注入,如下所示:

@Inject
public RecyclerAdapter(DataProviderListener dataProviderListener, DataSetChangeListener listener) {
        App.getAppComponent().inject(this);
        ...

通过阅读我已完成的示例项目,您可以了解有关在Android项目中使用dagger的更多信息:

  

https://github.com/mmirhoseini/fyber_mobile_offers