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


当前回答

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

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附加到onBindView。我真的不知道这是否会影响性能,但它似乎用很少的代码就能很好地工作。

public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "Recycle Click" + position, Toast.LENGTH_SHORT).show();
            }
    });
}

以下是我所做的。这个解决方案同时支持onClick和onLongClick在两个RecyclerView项目和视图内的RecyclerView项目(内部视图)。

我在我选择的视图上标记viewHolder:

public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item, null);
    ViewHolder viewHolder = new ViewHolder(itemView);

    itemView.setOnClickListener( this);
    itemView.setOnLongClickListener(this);
    viewHolder.imageIV.setOnClickListener(this);
    viewHolder.imageIV.setOnLongClickListener(this);

    viewHolder.imageIV.setTag(viewHolder);
    itemView.setTag(viewHolder);

    return viewHolder;
}

我使用holder.getPosition()在onClick()方法中检索位置(onLongClick类似):

public void onClick(View view) {
    ViewHolder holder = (ViewHolder) view.getTag();
    int position = holder.getPosition();

    if (view.getId() == holder.imageIV.getId()){
        Toast.makeText(context, "imageIV onClick at" + position, Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(context, "RecyclerView Item onClick at " + position, Toast.LENGTH_SHORT).show();
    }
}

带有getChildPosition的变体也可以工作。请注意,对于内部视图,在onClick()中使用:

int position = recyclerView.getChildPosition((View)view.getParent());

在我看来,这个解决方案的优点是,当一个人点击图像,只有onclick()图像侦听器被调用,而当我结合Jacob的解决方案为一个RecyclerView项目视图和我的解决方案为内部视图的RecyclerView项目视图onclick()也被调用(当点击图像)。

别白费力气了!这个特定用例的代码包含在Android Studio附带的Master/Detail Flow启动器项目中。

从Android Studio选择:

文件>新建>新建项目.... 在Phone and Tablet选项卡中选择如下所示的Master/Detail Flow。

用Kotlin或Java创建项目。 利润。

我不会在这里包括谷歌的ootb演示项目的代码,但我会概述谷歌提供的示例中的主要设计方法:

the item OnClickListener is created ONLY ONCE, and is assigned to a field in your RecyclerView.Adapter implementation. in the onBindViewHolder() you should set the same, pre-created onClickListener object on your ViewHolder instance with holder.itemView.setOnClickListener(mOnClickListener) (AVOID creating a new instance on every method call!); if you need to capture clicks on some specific elements inside the ViewHolder then extend ViewHolder and expose the elements you need as fields so that you can attach whatever listeners you need in onBindViewHolder() — and once again, do NOT re-create the listeners on every method call — initialise them as instance fields and attach them as needed. you can use .setTag() in order to pass state to your viewHolder, e.g. holder.itemView.setTag(mValues.get(position)); as used in the demo.

在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)

就是这样。

试试这个,很简单。这对我很管用。顺便说一句,我发现setOnClickListener对RecyclerView不生效。

recycler.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            // anything todo
        }

        return true;
    }
});