RecyclerView:如何捕捉ImageView的onClick事件?

8

我在RecyclerView的CardViews中有一个ImageView。 我想要像我已经在ListView中做过的那样,捕获ImageView上的onClick。所以,在public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position)中,我尝试了以下代码:

 myViewHolder.imageView.setClickable(true);
 myViewHolder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               Log.d("TEST", "Clicked");
            }

但是这完全被忽略了。下面的代码可以工作:
 myViewHolder.imageView.setImageResource(R.drawable.star_yellow);

What can I do?


你能否发布一下你的xm文件,以及onBindViewHolder和ViewHolder本身?我有一个项目,其中包含在CardView内部的ImageViews,onClick功能正常。 - Kistamushken
如果这不起作用,请发布您的布局。该链接是关于如何在使用RecyclerView填充的CardView中添加按钮的点击侦听器的问题。 - Pavan
2个回答

19

这是我的项目实践:

  1. 在项目中某处定义一个接口类:

    public interface RecyclerViewClickListener {
    
        void onRowClicked(int position);
        void onViewClicked(View v, int position);
    }
    
  2. 在你的RecyclerView.Adapter类中,将这个接口作为一个字段添加,并通过构造函数将其传递给适配器:

  3. public class YourRecAdapter extends RecyclerView.Adapter<YourRecAdapter.SimpleViewHolder>{
    
        private RecyclerViewClickListener listener;
    
        public YourRecAdapter(RecyclerViewClickListener listener){
            this.listener = listener;
        }
    
        public static class SimpleViewHolder extends RecyclerView.ViewHolder {
    
            public SimpleViewHolder(View itemView, final RecyclerViewClickListener listener) {
                super(itemView);
    
                // find view ids here
    
                itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(listener != null)
                            listener.onRowClicked(getAdapterPosition());
                    }
                });
    
                someViewholderView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(listener != null)
                            listener.onViewClicked(v, getAdapterPosition());
                    }
                });
            }
        }
    }
    
  4. 在您的Activity / Fragment中实现接口:

  5. public class YourFragment extends Fragment implements RecyclerViewClickListener {
    
       @Override
       public void onViewClicked(View v, int position) {
           if(v.getId == R.id.yourDesiredView){
               // Do your stuff here
           }
       }
    
       @Override
       public void onRowClicked(int position) {
           // Clicked entire row
       }
    }
    

谢谢您的回复,但是在onBindViewHolder方法中管理点击不是可能的吗? - helloimyourmind
是的,只需将所有的 ".setOnClickListener(...)" 代码移到 onBindViewHolder() 方法中即可。这样你就不必将监听器传递给 ViewHolder 的构造函数了。然而,我认为在 ViewHolder 中添加 onClick 方法稍微更有效一些,否则当你滚动列表时它们会一直被重新创建。 - Tomislav Turcic
在我的MyFragment类中,我需要创建一个RecyclerViewClickListener类型的新对象,并将其作为参数传递到Adapter构造函数中吗? - helloimyourmind
是的,只需将“this”作为参数传递,并让您的Fragment实现该接口。根据需要向适配器添加任何其他参数(数据、上下文等)。 - Tomislav Turcic
嗨@Tomislav。我正在尝试按照你在这里解释的方式进行操作,但我无法从我的片段中调用接口。我已经发布了一篇关于此问题的帖子(http://stackoverflow.com/questions/38954507/my-interface-class-dont-work-when-i-call-it-from-a-fragment)。你能否看一下并找出问题所在?谢谢! - S.P.
嘿,这个答案很老了,但也许你可以回答我的问题:在onViewItemClicked中,你传递View以在Activity的实现中查询它。但是你必须在多个视图上设置该侦听器才有意义,对吧?我的意思是,“someViewHolderView”代表一个单独的视图,你必须在多个不同的视图上设置onClickListner来查询ID? - Florian Walther

0
在您的Viewholder类中,您可以设置OnClickListener,但是为了将您的OnClick注册传回适配器(或任何您打算的目标),您需要另一个接口。

抱歉,这取决于您在OnClick中尝试做什么。如果您正在ViewHolder内部执行可以本地完成的操作(例如仅调整图像大小),则不需要接口或任何其他将OnClick传递回适配器的方法。但是,如果您尝试保存并移动到新活动或切换到ViewHolder没有引用的图像,则需要一个自定义侦听器(即接口),ViewHolder具有对其的引用,然后拥有活动或适配器可以监听。 - Devsil
我需要在onBindViewHolder中执行操作。 - helloimyourmind

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