有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。


当前回答

步骤1)编写点击界面

创建一个名为RecyclerViewClickListener.java的接口,并添加以下代码。这里我们声明了两个方法onClick和onLongClick,分别用于标识项目单击和长单击。

package com.androidtutorialshub.recyclerviewtutorial.Helper;

import android.view.View;

public interface RecyclerViewClickListener {
    void onClick(View view, int position);

    void onLongClick(View view, int position);
}

步骤2)编写项目触摸类

创建一个名为RecyclerViewTouchListener.java的类,并添加以下代码。这里我们编写了检测点击和长按回收器视图项的逻辑。

package com.androidtutorialshub.recyclerviewtutorial.Helper;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;


public class RecyclerViewTouchListener implements RecyclerView.OnItemTouchListener{

    private GestureDetector gestureDetector;
    private RecyclerViewClickListener clickListener;

    public RecyclerViewTouchListener(Context context, final RecyclerView recyclerView, final RecyclerViewClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child, recyclerView.getChildPosition(child));
                }
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

步骤3)定义点击监听器

打开MainActivity.java并更新以下更改。这里onClick()方法将检测点击项目,onLongClick将检测长时间点击项目。

recyclerView.addOnItemTouchListener(new RecyclerViewTouchListener(getApplicationContext(), recyclerView, new RecyclerViewClickListener() {
            @Override
            public void onClick(View view, int position) {
                Toast.makeText(getApplicationContext(), bookList.get(position).getTitle() + " is clicked!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLongClick(View view, int position) {
                Toast.makeText(getApplicationContext(), bookList.get(position).getTitle() + " is long pressed!", Toast.LENGTH_SHORT).show();

            }
        }));

欲了解更多信息或下载源代码:http://www.androidtutorialshub.com/android-recyclerview-click-listener-tutorial/

其他回答

这就是我最后需要的东西,以防有人发现它有用:

public static class ViewHolder extends RecyclerView.ViewHolder {

    public ViewHolder(View item) {

        super(item);
        item.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("RecyclerView", "onClick:" + getAdapterPosition());
            }
        });

    }
}

来源:http://blog.csdn.net/jwzhangjie/article/details/36868515

这里有一个更好的和不那么紧密耦合的方式来实现一个OnClickListener的RecyclerView。

用法片段:

RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
    new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
      @Override public void onItemClick(View view, int position) {
        // do whatever
      }

      @Override public void onLongItemClick(View view, int position) {
        // do whatever
      }
    })
);

RecyclerItemClickListener实现:

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;


public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
  private OnItemClickListener mListener;

  public interface OnItemClickListener {
    public void onItemClick(View view, int position);

    public void onLongItemClick(View view, int position);
  }

  GestureDetector mGestureDetector;

  public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
    mListener = listener;
    mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null && mListener != null) {
                mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
            }
        }
    });
}

  @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
    View childView = view.findChildViewUnder(e.getX(), e.getY());
    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
      mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
      return true;
    }
    return false;
  }

  @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

  @Override
  public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}

如果你想在个别项目上捕捉点击事件,那么只需在ViewHolder类中实现OnClickListener,然后在个别视图或整个itemView上设置点击侦听器。

下面的例子说明了同样的情况

public  class ContactViewHolder extends RecyclerView.ViewHolder implements OnClickListener
    {
        TextView txt_title,txt_name,txt_email;

        public ContactViewHolder(View itemView) 
        {
            super(itemView);
            txt_title = (TextView)itemView.findViewById(R.id.txt_title);
            txt_name  = (TextView)itemView.findViewById(R.id.txt_name);
            txt_email = (TextView)itemView.findViewById(R.id.txt_email);

            txt_name.setOnClickListener(this);
            txt_email.setOnClickListener(this);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            if(v == itemView)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Visiting Card Clicked is ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
            }

            if(v == txt_name)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Name ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
            }

            if(v == txt_email)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Email ==>"+txt_email.getText(), Toast.LENGTH_SHORT).show();
            }
        }

    }
} 

我已经看了所有的答案,并不是很满意。我找到了更简单快捷的方法。想分享给未来的读者。

选择单个回收项目中的任何视图。 获取这个View的父视图(确保你施放了合适的ViewGroup) 将onClickListener设置为这个父节点。

示例代码(它是在适配器的onBindViewHolder方法中编写的):

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {

    ConstraintLayout parent = (ConstraintLayout) holder.title.getParent();
    parent.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(context, "Clicked recycler view item at position " + position, Toast.LENGTH_SHORT).show();
        }
    });
}

在kotlin中使用构造函数实现

初始化你的RecyclerView构造函数,如下所示:

class ListAdapter(
    c: Context,
    private var list: List<Project>,
    private val itemClick: (Project) -> Unit
) : RecyclerView.Adapter<ListAdapter.ViewHolder>() 

在onCreateViewHolder中使用itemClick返回:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):ProjectViewHolder {
    val view = inflater.inflate(R.layout.list_item, parent, false)
    return ViewHolder(view, itemClick)
}

你的onBindViewHolder:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.bindProject(list[position])
}

然后用ViewHolder类创建bindProject函数。

class ViewHolder(
    view: View,
    private val itemClick: (Project) -> Unit
) : RecyclerView.ViewHolder(view) {

    private val clientTextCount = 7

    val titleTextView: TextView = view.projectTitleTextView
 
    fun bindProject(project: Project) {
        with(project) {
            titleTextView.text = name
            itemView.setOnClickListener { itemClick(this) }
        }
    }
}

最后在您的活动中用lazy初始化适配器

private val adapter: ListAdapter by lazy {
    ListAdapter(this, projectList, {
        // Here you can implement your onClick function.
    })
}

在适配器中为RecyclerView添加新列表初始化以下方法:

fun setProjects(projects: List<Project>) {
    projectList = projects
    notifyDataSetChanged()
}

在你的活动中调用setProjects方法:

adapter.setProjects(projects)

就是这样。