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


当前回答

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

选择单个回收项目中的任何视图。 获取这个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();
        }
    });
}

其他回答

下面是我的代码片段:

v.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        int newPosition = MainActivity.mRecyclerView.getChildAdapterPosition(v);
        Intent cardViewIntent = new Intent(c, MainActivityCards.class);
        cardViewIntent.putExtra("Position", newPosition);
        c.startActivity(cardViewIntent);
    }
});

v是onCreateViewHolder的视图 c为背景信息

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

就是这样。

您可以将clickListener传递给适配器。

在活动中:

private View.OnClickListener mItemClick = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        Intent intent = null;
        int position = list.getChildPosition(v);
        switch (position) {
            case 0:
                intent = new Intent(MainActivity.this, LeakCanaryActivity.class);
                break;
            case 1:
                intent = new Intent(MainActivity.this, ButterKnifeFragmentActivity.class);
                break;
        }
        if (intent != null) {
            MainActivity.this.startActivity(intent);
        }
    }
};

然后将它传递给适配器:

MainAdapter mainAdapter = new MainAdapter(this, mItemClick);

在适配器的onCreateViewHolder中:

 @Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
    View itemView = activity.getLayoutInflater().inflate(R.layout.main_adapter_item, viewGroup, false);
    ViewHolder holder = new ViewHolder(itemView);
    itemView.setOnClickListener(mItemClick);
    return holder;
}

这是我的自定义适配器的完整代码,这段代码将用XML文件“list_item”中定义的列表项膨胀行,它还将在具有各自位置的所有列表项行上执行单击事件。

public class MyCustomAdapter extends RecyclerView.Adapter`<`AdapterMyCustomAdapter.ViewHolder> {

    public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
        public onItemClickListener mListener;
        public ViewHolder(View v, onItemClickListener listener) {
            super(v);
            mListener =listener;
            v.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            mListener.onRecyclerItemClick(v, getPosition());
        }

        public static interface onItemClickListener {
            public void onRecyclerItemClick(View view , int position);
        }
    }

    @Override
    public int getItemCount() {
        return 5;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int pos) {      

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item, parent, false);

    /* here list_item is an xml file we want to inflate ...it is same as we do in case of listview for customization.*/

        MyCustomAdapter.ViewHolder vh = new ViewHolder(v, new MyCustomAdapter.ViewHolder.onItemClickListener() {

            @Override
            public void onRecyclerItemClick(View view, int position) {
                System.out.println("clicked on list item at position " +position);
            } 
        });
        return vh;
    }
}

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

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

        return true;
    }
});