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


当前回答

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

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

        return true;
    }
});

其他回答

有更简单的方法。只需要在根视图上应用onBindViewHolder中的click。

考虑这是你对适配器的看法,

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/linearlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <TextView
            android:id="@+id/textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="1dp"
            android:textSize="15sp" />
</LinearLayout>

然后在适配器中执行以下操作

//get the layout and make view holder
@Override
public RVAdapter.ViewHolder1 onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_layout, null);
    ViewHolder1 viewHolder = new ViewHolder1(view);
    return viewHolder;
}

@Override
public void onBindViewHolder(RVAdapter.ViewHolder1 holder, int position) {

    //apply on click on your root view
    holder.linearlayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Do on click stuff
        }
    });
}

//make references to views in layout including root view
public class ViewHolder1 extends RecyclerView.ViewHolder {

    protected LinearLayout linearlayout = null
    protected TextView textview = null;

    public CareerLinksViewHolder(View itemView) {
        super(itemView);

        this.linearlayout = (LinearLayout) itemView.findViewById(R.id.linearlayout);
        this.tvCompName = (TextView) itemView.findViewById(R.id.textview);
    }
}

我知道有很多答案,但我想我也可以提供我的实现。(完整的细节可以在我回答的另一个问题中找到)。

所以,要添加一个点击监听器,你的内部ViewHolder类需要实现View.OnClickListener。这是因为你将设置一个OnClickListener到ViewHolder的构造函数的itemView参数。让我来告诉你我的意思:

public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    TextView text1, text2;

    ExampleClickViewHolder(View itemView) {
        super(itemView);

        // we do this because we want to check when an item has been clicked:
        itemView.setOnClickListener(this);

        // now, like before, we assign our View variables
        title = (TextView) itemView.findViewById(R.id.text1);
        subtitle = (TextView) itemView.findViewById(R.id.text2);
    }

    @Override
    public void onClick(View v) {
        // The user may not set a click listener for list items, in which case our listener
        // will be null, so we need to check for this
        if (mOnEntryClickListener != null) {
            mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
        }
    }
}

唯一需要添加的其他东西是适配器的自定义接口和setter方法:

private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}

这样,新的支持单击的适配器就完成了。

现在,让我们用它…

    ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects);
    clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() {
        @Override
        public void onEntryClick(View view, int position) {
            // stuff that will happen when a list item is clicked
        }
    });

这基本上就是设置普通适配器的方法,除了使用您创建的setter方法来控制当用户单击特定列表项时要做什么。

你也可以看看我在GitHub上做的一组关于Gist的例子:

https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07

由于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的方法。OnClickListener:

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyviewHolder>
    implements View.OnClickListener

在ViewHoder中获取项目布局的父视图:

public class MyviewHolder extends RecyclerView.ViewHolder {

    LinearLayout linearLayout;

    public MyviewHolder(View itemView) {
        super(itemView);
        linearLayout = itemView.findViewById(R.id.linear_layout_item);
    }
}

在onBindViewHolder中设置标签为位置:

@Override
public void onBindViewHolder(MyviewHolder holder, int position) {
    holder.linearLayout.setTag(position);
    holder.linearLayout.setOnClickListener(this);
}

在你的onClick实现中:

@Override
public void onClick(View v) {
    int position = (int) v.getTag();

    switch (v.getId()) {
        case R.id.linear_layout_item:
            // do some thing with position 
            break;
    }
}

不幸的是,RecyclerView缺少ListView内置的几个功能。 例如,添加OnItemClickListener的能力,当一个项目被单击时触发。 RecyclerView允许你在适配器中设置一个OnClickListener,但是传递那个点击 从你的调用代码,到适配器,再到ViewHolder,监听器是复杂的 要捕捉一个简单的项目单击。

public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mOnItemClickListener != null) {
            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
            mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
        }
    }
};
private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        if (mOnItemLongClickListener != null) {
            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
            return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
        }
        return false;
    }
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
        = new RecyclerView.OnChildAttachStateChangeListener() {
    @Override
    public void onChildViewAttachedToWindow(View view) {
        if (mOnItemClickListener != null) {
            view.setOnClickListener(mOnClickListener);
        }
        if (mOnItemLongClickListener != null) {
            view.setOnLongClickListener(mOnLongClickListener);
        }
    }

    @Override
    public void onChildViewDetachedFromWindow(View view) {

    }
};

private ItemClickSupport(RecyclerView recyclerView) {
    mRecyclerView = recyclerView;
    mRecyclerView.setTag(R.id.item_click_support, this);
    mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}

public static ItemClickSupport addTo(RecyclerView view) {
    ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
    if (support == null) {
        support = new ItemClickSupport(view);
    }
    return support;
}

public static ItemClickSupport removeFrom(RecyclerView view) {
    ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
    if (support != null) {
        support.detach(view);
    }
    return support;
}

public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
    mOnItemClickListener = listener;
    return this;
}

public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
    mOnItemLongClickListener = listener;
    return this;
}

private void detach(RecyclerView view) {
    view.removeOnChildAttachStateChangeListener(mAttachListener);
    view.setTag(R.id.item_click_support, null);
}

public interface OnItemClickListener {

    void onItemClicked(RecyclerView recyclerView, int position, View v);
}

public interface OnItemLongClickListener {

    boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
}
}

您还需要定义R.id。使用ids.xml:

 <?xml version="1.0" encoding="utf-8"?>
 <resources>
  <item name="item_click_support" type="id" />
 </resources>

结果代码点击侦听器现在看起来像这样:

ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
    // do it
}
});

关于recyclerview点击的简要说明,请看看这个littlerobots_blog