RecyclerView CardView onItemClick

时间:2015-08-12 16:56:57

标签: android android-recyclerview android-cardview

坚持这个问题几天希望找到解决方案。

我无法将卡上写的数据(卡片视图)传递给下一个活动。

对于点击卡片,我在其recyclerView适配器中实现了onClickListner。

我想通过卡片的位置点击,但由于卡片视图不支持onItemClickListner我面临的问题。

RecyclerViewAdapter类

public class RVAdapter extends recyclerView.Adapter<RVAdapter.PersonViewHolder> implements View.OnClickListener, View.OnLongClickListener {

 int position;
  @Override
public void onBindViewHolder(PersonViewHolder holder, int i) {
    setEventsForViews(holder, i);
}

private void setEventsForViews(PersonViewHolder holder, int i) {
    position = i;
    holder.cv.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    Navigator.toAddFriends(context, placeList.get(getPosition()).getPlaceId());
}

public static class PersonViewHolder extends RecyclerView.ViewHolder {
    CardView cv;

    PersonViewHolder(View itemView) {
        super(itemView);
        cv = (CardView) itemView.findViewById(R.id.cv);
    }

}

我试图设置一个变量位置并试图传递它的值,但是因为onBindViewHolder被初始调用视图中的所有项目,所以我最终将位置值设置为最后一个。我知道这是错误的方法,但由于我是这张卡片的新手,请向我建议任何干净利落的方法。

提前致谢。

1 个答案:

答案 0 :(得分:3)

创建一个新界面,例如:

public interface RecyclerViewClickListener {
public void recyclerViewListClicked(View v, int position);
}

在Fragment / Activity上,实现新界面:

public class MyFragment extends BaseFragment implements RecyclerViewClickListener { }

现在,您将被迫在Fragment / Activity上实现接口方法recyclerViewListClicked(View v, int position)。 这样做可以在单击一个项目时执行任何操作。这样做:

 @Override
public void recyclerViewListClicked(View v, int position) {
    myList.get(position);
}

现在让我们转到您的适配器。 在适配器构造函数上,添加一个新的侦听器参数。 类型是我们刚刚创建的接口(不要忘记创建私有静态侦听器并在构造函数上设置它):

private static RecyclerViewClickListener mListener;

public myListAdapter(List<Thing> things, final Context context, RecyclerViewClickListener itemClickListener) {
    mThings = things;
    mContext = context;

    mListener = itemClickListener;
}

在适配器内部,在ViewHolder上,实现View.OnClickListener,如:

public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener

现在,您将被迫在ViewHolder中执行@Override onClickMethod。这样做:

    @Override
    public void onClick(View v) { }

在ViewHolder构造函数中,设置视图的onClickListener。像:

public MyViewHolder(View view) {
        super(view);
        ButterKnife.bind(this, view);

        myCardViewLayout.setOnClickListener(this);
    }

现在将行为实施到ViewHolder onClickMethod。在这种情况下,我调用我们在适配器中声明的静态侦听器的recyclerViewListClicked方法。这个方法是我们在片段/活动中有@Overriden的方法,所以它需要position参数。

通过在视图持有者中调用getLayoutPosition()来获取该位置。它看起来像这样:

    @Override
    public void onClick(View v) {
        mListener.recyclerViewListClicked(v, getLayoutPosition());
    }

最后,回到你的片段/活动,并将监听器传递给带有this的适配器构造函数(因为现在我们实现了接口RecyclerViewClickListener它只能将自己作为监听器传递给适配器):

mRecyclerView.setAdapter(new MyListAdapter(this.mList, this.getActivity(), this))

现在,当您点击列表项目的myCardViewLayout时,它将调用您的片段/活动的recyclerViewListClicked(View v, int position),您可以根据需要使用位置参数。 您可以对要从列表中获取单击事件的任何布局执行此操作。只需使用myCardViewLayout.setOnClickListener(this)替换ViewHolder构造函数中的myDesiredToHaveOnClickListenerLayout.setOnClickListener(this)

希望这有帮助。

@EDIT:

一些提示:

  • 从适配器中删除implements View.OnClickListener, View.OnLongClickListener

  • 看起来您不再需要setEventsForViews(holder, i)上的onBindViewHolder了。确认?

@UPDATE 这就是ViewHolder的样子:

public static class PersonViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    CardView cv;

    PersonViewHolder(View itemView) {
        super(itemView);
        cv = (CardView) itemView.findViewById(R.id.cv);

        cv.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        mListener.recyclerViewListClicked(v, getLayoutPosition());
    }

}