【问题标题】:How to add OnClickListner to CardView?如何将 OnClickListener 添加到 CardView?
【发布时间】:2015-05-09 16:21:05
【问题描述】:

我正在与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);
    }
}
}

正如大家所看到的,我尝试了setOnClickListeneronCreateViewHolderonBindViewHolder,也作为单独的onClick,但它们似乎都不适合我。所以,我想知道,如何将 OnClickListner 添加到 CardView?

【问题讨论】:

  • 你能提供你的 XML 布局文件吗?

标签: android onclicklistener android-cardview android-recyclerview


【解决方案1】:

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

【讨论】:

  • 嗨,它对OnClickListener 有效,但对OnLongClickListener 显示错误。另外我认为您的代码示例中的意思是View.OnClickListener。我会标记最佳答案,一旦我得到它也为OnLongClickListener 工作。谢谢。给我点赞。
  • 2.另外,有什么方法可以实现这样的事情 - viewHolder.setOnClickListener
  • 我现在明白了,你混合了onClickLinstner(需要setOnClickListener)和onLongClickListner。(需要setOnLongClickListener)。您的建议在这些更正后有效。请纠正他们。但我找不到直接获取viewHolder.setOnClickListener 的方法,除了使用onClickListner 进行整个布局。谢谢。
  • 哇,你在同一时间编辑,而我在 cmets 中提到相同。 :P
  • 谢谢。回答你的#2 是的,你可以。如果您有行的根 ID R.layout.subject_cardview_row,我假设它是 CardView,那么您可以像 TextView tvSubjectName, tvCounts 一样获得 ViewHolder 中的引用。然后你可以给它附加一个点击监听器。
【解决方案2】:

这对我有用! 将 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,在他的回答中)。给我点赞。
  • 好的,我明白了。我会尝试使用整数,但即便如此,我也无法获得额外的信息,比如 subject.getSubject_Name()onBindViewHolder 中,或者有什么办法吗?
  • 尝试在 onClick 中使用 v.findViewById() 并使用 TextView 获取您想要的额外信息。我认为有更好的方法来获取额外信息,但这是您可以尝试的方法。
  • 嘿,感谢您一直以来的支持,但我已经得到了我需要的一切,从修改@inmyth 的答案(我在他的答案中评论他的错误)。希望我能为您的帮助加倍投票:)
  • @inmyth 使用的方法和我一样,只是代码在不同的地方。
【解决方案3】:

查看 Lucas Rocha 的新 TwoWayView API。

TwoWayLayoutManager 是 LayoutManager 之上的一个简单 API,它为您完成所有繁重的工作,因此您可以专注于如何测量、放置子视图以及从 RecyclerView 分离。

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

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

【讨论】:

    【解决方案4】:

    在 RecyclerView.ViewHolder 构造函数中将 OnClickListener 设置为 itemView,您也可以使用 getAdapterPosition() 方法获取 cardView 的位置,这可以帮助您使用 putExtra 意图方法将数据传递给新活动。 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
                }
            });
    }
    

    `

    【讨论】:

      【解决方案5】:

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

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

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

      这将适用于整个 cardView

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-18
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多