2017-08-31 87 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