2016-10-11 6 views
1

alle!Injektion von Aktivität und Fragment in RecyclerAdapter (Dolch 2)

Ich bin ziemlich neu in Dagger2, aber ich will es wirklich verstehen. Sehen wir uns zunächst den Code des RecyclerAdapters an, den ich mit einigen Injektionen auf Anwendungsebene implementiert habe (DbHelper und Anwendungskontext).

auch bemerken, dass hier haben wir zwei Instanzen von DataSetChangeListener und DataProviderListener:

  • DataSetChangeListener - ist eine Schnittstelle, einige Methoden in Fragmente zu nennen (die Ansichten ist die Verwaltung);
  • DataProviderListener - ist eine Schnittstelle zum Aufrufen von Methoden in Activity (die die Datenmodellaufrufe verwaltet);

So, hier ist der Code:

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


} 

Mir ist klar, dass theoretisch könnte ich DataSetChangeListener und DataProviderListener, injizieren, aber wie könnte ich das tun. Vielleicht geht es um die Schaffung eines neuen Geltungsbereichs? Aber ich habe keine Ahnung, wie man es benutzt. Wie kann ich diese beiden Objekte im RecyclerAdapter instanziieren, wenn ich nicht einmal in der Lage bin, sie aus der RecyclerAdapter-Klasse zu referenzieren. Das Übergeben von Instanzen als Konstruktordarsteller ist noch kein DI. Was soll ich hier machen?

+0

ich würde eher insi injizieren de Fragment/Aktivität, was ich brauche, und übergebe es als Parameter im Adapter. –

Antwort

2

Alle Änderungen, um Ihr Projekt mit mehr Dagger und Dependency Injection zu machen, hängen von Ihrer gesamten Projektstruktur ab! Aber, wenn Sie diese beiden Schnittstellen injizieren möchten, können Sie einen Provider Methode für RecyclerAdapter schreiben und diese Schnittstellen, um es in Ihrem Modul injizieren:

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

beachten Sie, dass: ein anderer Provider oder Modul-Konstruktor bereitstellen muss diese Schnittstellen während der Injektion.

Sie können tun, auch Constructor Injection von @Inject Anmerkung zu Ihrem RecyclerAdapter Konstruktor wie folgt ergänzt:

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

Sie können erfahren Sie mehr über Dolch in Android-Projekt mit durch dieses Beispielprojekt Lesen ich getan habe:

https://github.com/mmirhoseini/fyber_mobile_offers

Verwandte Themen