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


当前回答

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

适配器的构造函数

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);
}

其他回答

对我来说,这是最好的方法:

class YourRecyclerAdapter extends RecyclerView.Adapter<ContactViewHolder> implements View.OnClickListener { 
  ...
  @Override
  public void onClick(View view) {
        int itemPosition = vRecycle.getChildPosition(view);
        //And use itemPosition to get the item from your collection. This way you dont restrain the ViewHolder with a OnClick callback
    }
  ...
}

由于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();
}

这对我来说很管用。将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()也被调用(当点击图像)。

通常你在CardView中有多个元素,所以你需要一个布局视图来包装和组织它们。你可以添加一个OnClickListener到那个布局视图。1. 添加一个id到你的布局。在这个例子中是线性布局

<android.support.v7.widget.CardView
 .....>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/card_view_linearLayout">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="name"
            android:id="@+id/card_view_name" />

        ...

    </LinearLayout>

</android.support.v7.widget.CardView>

2美元。在你的内部ViewHolder类中获取布局视图。

public static class ViewHolder extends RecyclerView.ViewHolder{
    private TextView nameView;
    ...
    private LinearLayout linearLayout;
    public ViewHolder(View itemView) {
        super(itemView);
        nameView = (TextView)itemView.findViewById(R.id.card_view_name);
        ...
        linearLayout = (LinearLayout)itemView.findViewById(R.id.card_view_linearLayout);
    }
}

3美元。将监听器添加到onBindViewHolder中的布局中,并使用回调将数据发送到活动或片段(未测试)。

@Override
public void onBindViewHolder(TrackAdapter.ViewHolder holder, final int position) {
    String str = mStringList.get(position);

    holder.nameView.setText(str);
    ...
    holder.linearLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            callback.itemCallback(mStringList.get(position));
        }
    });
}

如何使用回调是另一个故事