2017-08-31 120 views
5

實施onItemClickListener我學習MVP和糊塗了其中如何應該怎麼實現OnClickListener雖然這裏沒有破壞MVP的概念。使用MVP模式

按照本指南:https://android.jlelse.eu/recyclerview-in-mvp-passive-views-approach-8dd74633158

我的實現。

適配器:

public class RepositoriesRecyclerAdapter extends RecyclerView.Adapter<RepositoriesRecyclerAdapter.RepoViewHolder> { 


private final RepositoriesListPresenter presenter; 

public RepositoriesRecyclerAdapter(RepositoriesListPresenter repositoriesPresenter) { 
    this.presenter = repositoriesPresenter; 
} 

@Override 
public RepositoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    return new RepositoryViewHolder(LayoutInflater.from(parent.getContext()) 
              .inflate(R.layout.cell_repo_view, parent, false)); 
} 

@Override 
public void onBindViewHolder(RepositoryViewHolder holder, int position) { 
    presenter.onBindRepositoryRowViewAtPosition(position, holder); 

} 

@Override 
public int getItemCount() { 
    return presenter.getRepositoriesRowsCount(); 
} 

} 

RepositoryViewHolder的

public class RepositoryViewHolder extends RecyclerView.ViewHolder implements RepositoryRowView { 

    TextView titleTextView; 
    TextView starsCountTextView; 

    public RepositoryViewHolder(View itemView) { 
     super(itemView); 
     titleTextView = itemView.findViewById(R.id.repoTitleText); 
     starsCountTextView = itemView.findViewById(R.id.repoStarsCountText); 
    } 

    @Override 
    public void setTitle(String title) { 
     titleTextView.setText(title); 
    } 

    @Override 
    public void setStarCount(int starCount) { 
     starsCountTextView.setText(String.format("%s ★", starCount)); 
    } 
} 

RepositoryRowView

interface RepositoryRowView { 

    void setTitle(String title); 

    void setStarCount(int starCount); 
} 

所有指南我看到的是關於適配器創建onClickListener對象,然後在ViewHolder使用它,但在這實現中,我重寫了演示者中的所有適配器功能並傳遞onClickListener(Android相關的東西)會矛盾的MVP模式。在這種情況下做什麼。也許有人可以寫一個解決方案 - 真的很困惑。

我的主要目標將是點擊recyclerview項目,並獲得項目名稱(通過吐司)

回答

4

OnClickListener是Android SDK中的接口。您的演示者不應該瞭解有關Andriod SDK的任何信息。它應該是純Java,所以可以通過在JVM上使用單元測試進行測試。它不應該知道任何關於視圖,RecyclerView,Adapter或ViewHolder。

您的onBindViewHolder不違反這個原則,因爲它被抽象接口--RepositoryRowView分開。

您應該在adapter/viewholder中實現OnClickListener並從那裏調用您的演示者。

public class RepositoryViewHolder extends RecyclerView.ViewHolder implements RepositoryRowView, View.OnClickListener { 

    TextView titleTextView; 
    TextView starsCountTextView; 
    RepositoriesListPresenter presenter; 

    public RepositoryViewHolder(View itemView, RepositoriesListPresenter presetner) { 
     super(itemView); 
     titleTextView = itemView.findViewById(R.id.repoTitleText); 
     starsCountTextView = itemView.findViewById(R.id.repoStarsCountText); 
     this.presenter = presenter; 
     itemView.setOnClickListener(this); 
    } 

    @Override 
    public void setTitle(String title) { 
     titleTextView.setText(title); 
    } 

    @Override 
    public void setStarCount(int starCount) { 
     starsCountTextView.setText(String.format("%s ★", starCount)); 
    } 

    @Override 
    public void onClick(View view) { 
     if (presenter != null) { 
      presenter.onItemInteraction(getAdapterPosition()); 
     } 
    } 
} 
+0

放什麼如果,例如,我想改變選定的項目的顏色? 我不能將項目傳遞給主持人(如前所述),但我可以通過該位置(如您所示),現在VIEW(片段)如何改變顏色或與位置有關的東西? – JoshuaMad

+1

@JoshuaMad你可以使用你已有的抽象。您可以傳遞位置和RepositoryRowView(由ViewHolder實現,因此您可以將「this」添加爲參數)傳遞給演示者。比你可以添加方法到RepositoryRowView類。像「markRowAs ...」這樣的東西以及它的實現將會改變顏色。 –

0

這很有趣。我有類似的情況,我必須趕上項目點擊並改變它的外觀。 (決定在這裏提出一個問題,因爲其他人也可能需要它) @JosefAdamcik給出了一個很好的示例,說明如何管理從abstration(ViewholderPresenter)的點擊,但如果在Adapter中設置了點擊,該怎麼辦?我可以從我的Adapter(通過點擊項目位置)通知Presenter,但我不能使用上面提到的抽象。

+0

請不要將問題張貼爲答案。改爲將問題發佈爲問題。 – WebDevBooster