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


当前回答

让我们看看如何在Jetpack / AndroidX中实现这一点

你需要像这样在viewmodel类中创建一个观察对象

private MutableLiveData<Integer> adapterItem = new MutableLiveData<>();

public MutableLiveData<Integer> getAdapterItem() {
    return adapterItem;
}

public void setAdapterItem(int adapterItem) {
    this.getAdapterItem().setValue(adapterItem);
}

然后在适配器类中,确保将viewmodel引用作为构造函数的参数传递,然后在vieholder上实现clicklistener

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        if(itemView != null){
            itemView.setOnClickListener(v -> {
                int adapterPosition = getAdapterPosition();
                viewModel.setAdapterItem(adapterPosition);
            });

        };
    }

然后从活动课上观察变化

    viewModel.getAdapterItem().observe(this, position -> {
        Log.w(TAG, "clicked: " + ridesArray.get(position));
    });

其他回答

对我来说,最干净的方法就是这个。

适配器的构造函数

private class EnvironmentTypeRecyclerViewAdapter extends RecyclerView.Adapter<EnvironmentTypeRecyclerViewAdapter.ViewHolder>
{
     private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener;
     private List<Environment> mEnvironmentsData;

     public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
     {
         public ViewHolder(View v)
         {
             super(v);
             v.setOnClickListener(this);

         }

         @Override
         public void onClick(View v)
         {
              Environment environment = mEnvironmentsData.get(getAdapterPosition());
              if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null) {
                      mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment);      
              }
        }

        public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener)
        {
            mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener;
            mEnvironmentsData = environments;
        }
}

链接接口

private interface EnvironmentTypeRecyclerViewAdapterListener
{
    void onListItemSelected(Environment environment);
}

由于API已经发生了根本性的变化,如果你要为每个项目创建一个OnClickListener,这不会让我感到惊讶。不过也没那么麻烦。在你的RecyclerView的实现中。适配器<MyViewHolder>,你应该有:

private final OnClickListener mOnClickListener = new MyOnClickListener();

@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
    View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
    view.setOnClickListener(mOnClickListener);
    return new MyViewHolder(view);
}

onClick方法:

@Override
public void onClick(final View view) {
    int itemPosition = mRecyclerView.getChildLayoutPosition(view);
    String item = mList.get(itemPosition);
    Toast.makeText(mContext, item, Toast.LENGTH_LONG).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();
        }
    });
}

别白费力气了!这个特定用例的代码包含在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)

就是这样。