如何将 OnClickListener 添加到 CardView?

How to add OnClickListner to CardView?

我正在与 RecyclerViewCardView 合作。我想在每张卡片上附加 OnClickListner。我尝试了 Whosebug 上的许多可用答案,但它们对我不起作用。到目前为止我已经尝试过 -

public class SubjectAdapter extends RecyclerView.Adapter<SubjectAdapter.ViewHolder> implements View.OnClickListener,
    View.OnLongClickListener{

private static final String LOGCAT = "SubjectAdapter";
private final Context mContext;

List<Subject> SubjectsList;

public SubjectAdapter(Context context) {
    super();
    this.mContext = context;
    SQLiteDatabase.loadLibs(mContext);
    DBHelper myDbHelper = new DBHelper(mContext);
    SubjectsList = new ArrayList<Subject>();
    SubjectsList = myDbHelper.getAllSubjects();
    myDbHelper.close();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.subject_cardview_row, viewGroup, false);
    ViewHolder viewHolder = new ViewHolder(v);

    // Below two lines are NOT working
    viewHolder.tvSubjectName.setOnClickListener(this);
    //viewHolder.setOnClickListener(this);

    return viewHolder;
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    Subject subject = SubjectsList.get(i);
    viewHolder.tvSubjectName.setText(subject.getSubject_Name());
    viewHolder.tvCounts.setText(String.valueOf(subject.getSubject_Number_of_Questions()));

    // Below two lines are NOT working
    viewHolder.tvSubjectName.setOnClickListener(this);
    //viewHolder.setOnClickListener(this);
}

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

@Override
public void onClick(View v) {
    // It's not working either
    ViewHolder holder = (ViewHolder) v.getTag();
    int position = holder.getPosition();

    if (v.getId() == holder.tvSubjectName.getId()){
        Log.d(LOGCAT, "tvSubjectName onClick at" + position);
        //Toast.makeText(mContext, "tvSubjectName onClick at" + position, Toast.LENGTH_LONG).show();
    } else {
        Log.d(LOGCAT, "RecyclerView Item onClick at " + position);
        //Toast.makeText(mContext, "RecyclerView Item onClick at " + position, Toast.LENGTH_LONG).show();
    }
}

@Override
public boolean onLongClick(View v) {
    return false;
}

class ViewHolder extends RecyclerView.ViewHolder {

    public TextView tvSubjectName;
    public TextView tvCounts;

    public ViewHolder(View itemView) {
        super(itemView);
        tvSubjectName = (TextView) itemView.findViewById(R.id.tv_subject_name);
        tvCounts = (TextView) itemView.findViewById(R.id.tv_text_counts);
    }
}
}

如你所见,我已经尝试 setOnClickListener 同时使用 onCreateViewHolderonBindViewHolder,也尝试使用单独的 onClick,但其中 none 似乎为我工作。所以,我想知道,如何将OnClickListner添加到CardView?

这对我有用! 将 setOnClickListener-method 放入 ViewHolder class.

的构造函数中
class ViewHolder extends RecyclerView.ViewHolder
{
    public TextView tvSubjectName;
    public TextView tvCounts;

    public ViewHolder(View itemView) 
    {
        super(itemView);
        tvSubjectName = (TextView) itemView.findViewById(R.id.tv_subject_name);
        tvCounts = (TextView) itemView.findViewById(R.id.tv_text_counts);

        itemView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                 //write here the code for wathever you want to do with a card
                 //...
            }
        });

}

}

onClick 返回的视图不一定对应回收器视图的视图行层次结构。 我认为您应该将 onBindViewHolder 修改为

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int i) {
   final Subject subject = SubjectsList.get(i); 
   viewHolder.tvSubjectName.setOnClickListener(new View.OnClickListener(){


    @Override
    public void onClick(View v) {
        Log.d(LOGCAT, "tvSubjectName onClick at" + i);
       // etc
    }

   });
...
}

如果您使用长按,则将 View.OnClickListener 替换为 View.OnLongClickListener,将 onClick 替换为 onLongClick

查看 Lucas Rocha 的新 TwoWayView API。

TwoWayLayoutManager is a simple API on top of LayoutManager that does all the laborious work for you so that you can focus on how the child views are measured, placed, and detached from the RecyclerView.

Follow his site 和 API 的实现相对简单,可能会帮助您解决 RecyclerView 和 CardView 的一些复杂问题。

http://lucasr.org/2014/07/31/the-new-twowayview/

在 RecyclerView.ViewHolder 构造函数中将 OnClickListener 设置为 itemView,您还可以使用 getAdapterPosition() 方法获取 cardView 的位置,这可以帮助您使用 putExtra 方法将数据传递给新的 activity意图。 doc for getAdapterPosition method

`

class ViewHolder extends RecyclerView.ViewHolder
{
    public TextView tvSubjectName;
    public TextView tvCounts;

    public ViewHolder(View itemView) 
    {
        super(itemView);
        tvSubjectName = (TextView) itemView.findViewById(R.id.tv_subject_name);
        tvCounts = (TextView) itemView.findViewById(R.id.tv_text_counts);

        itemView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                 int position = getAdapterPosition();
                 // use position to put extra data
            }
        });
}

`

如果您真的想实现 onclick 监听器,请执行以下操作

  1. 在您的 ViewHolderClass 中添加一个 View 对象,并将其初始化为在构造函数中收到的 itemView

2.setOnClickListener 到您在 Adapter 中的 onBindViewHolder 中声明的视图对象(在 ViewHolder 中)class

这将适用于整个 cardView