如何给CardView添加OnClickListner?

4

我正在使用RecyclerViewCardView。我希望为每个卡片附加OnClickListner。我尝试了stackoverflow上提供的许多答案,但它们对我不起作用。到目前为止,我已经尝试了以下方法:

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

正如您所看到的,我尝试过使用onCreateViewHolderonBindViewHolder,还分别使用onClick,但似乎都没有奏效。因此,我想知道如何在CardView上添加OnClickListner?


你可以提供你的XML布局文件吗? - Fouad Wahabi
5个回答

9

在RecyclerView中,通过onClick返回的View不一定对应着RecyclerView行层次结构中的View。我认为你应该修改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

嗨,它适用于OnClickListener,但对于OnLongClickListener显示错误。此外,我认为您在代码示例中想表达的是View.OnClickListener。我会尽快让它也适用于OnLongClickListener,然后标记最佳答案。谢谢。我给你点赞了。 - Dr. Atul Tiwari
此外,有没有任何方法可以实现像 viewHolder.setOnClickListener 这样的操作? - Dr. Atul Tiwari
我现在明白了,您混淆了 onClickLinstner(需要 setOnClickListener)和 onLongClickListner(需要 setOnLongClickListener)。在进行这些更正后,您的建议有效。请友善地纠正它们。但是,除了使用整个布局的 onClickListner,我找不到直接获取 viewHolder.setOnClickListener 的方法。谢谢。 - Dr. Atul Tiwari
哇,你在我刚才发评论的时候同时编辑了。 :P - Dr. Atul Tiwari
1
非常感谢。回答您的第二个问题,是的,您可以这样做。如果您有行根的ID R.layout.subject_cardview_row,我假设它是CardView,那么您可以通过与TextView tvSubjectName, tvCounts相同的方式在ViewHolder中获取引用。然后,您可以将单击侦听器附加到它。 - inmyth

4
这对我很有帮助! 将setOnClickListener-method方法放在您的ViewHolder类的构造函数中即可。
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
                 //...
            }
        });

}

}


它能工作,但每当我尝试获取位置时都会出现错误ViewHolder holder = (ViewHolder) v.getTag(); int position = holder.getPosition();即使我设法获得位置,我也无法获得额外的信息,而这是我能从@inmyth的答案(int i,在他的答案中)获得的。我给你点赞。 - Dr. Atul Tiwari
好的,我明白了。我会尝试使用整数,但即使这样,我也无法获得额外的信息,比如在onBindViewHolder中的subject.getSubject_Name(),或者有其他方法吗? - Dr. Atul Tiwari
尝试在onClick中使用v.findViewById(),并使用TextView获取您想要的额外信息。我认为有更好的方法来获取额外的信息,但这是一个可以尝试的方法。 - Nike Sprite
嘿,感谢您不断的支持,但我已经从修改@inmyth的答案中得到了我需要的一切(我正在评论他的答案中的错误)。希望我能为您的帮助投两票 :) - Dr. Atul Tiwari
@inmyth使用的方法和我一样,只是代码位于不同的位置。 - Nike Sprite

1

请查看Lucas Rocha的新的TwoWayView API。

TwoWayLayoutManager是在LayoutManager之上的一个简单API,可以为您完成所有繁琐的工作,以便您可以专注于如何测量、放置和分离RecyclerView中的子视图。

关注他的网站和实现该API相对简单,可能会帮助您解决RecyclerView和CardView带来的一些困难复杂性。

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


0
如果你真的想要实现onclick监听器,那么请按照以下步骤进行:
  1. 在您的ViewHolder类中添加一个View对象,并将其初始化为构造函数中接收到的itemView

2.在Adapter类的onBindViewHolder中对所声明的view对象设置setOnClickListener

这将适用于整个cardView。


0
在 RecyclerView.ViewHolder 构造函数中将 OnClickListener 设置为 itemView。此外,您可以使用 getAdapterPosition() 方法获取 cardView 的位置,这可以帮助您通过 Intent 的 putExtra 方法将数据传递到新的 Activity。getAdapterPosition 方法的文档

`

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

`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接