有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
我知道有很多答案,但我想我也可以提供我的实现。(完整的细节可以在我回答的另一个问题中找到)。
所以,要添加一个点击监听器,你的内部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
其他回答
我已经为android开发了一个轻量级的库,你可以访问github并遵循这个示例:
RecycleClick.addTo(YOUR_RECYCLE_VIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// Your code here
}
});
将类标记为抽象并实现OnClick方法
public abstract class MainGridAdapter extends
RecyclerView.Adapter<MainGridAdapter.ViewHolder> {
private List<MainListItem> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView txtHeader;
public TextView txtFooter;
public ViewHolder(View v) {
super(v);
txtHeader = (TextView) v.findViewById(R.id.firstLine);
txtFooter = (TextView) v.findViewById(R.id.secondLine);
}
}
public void add(int position, MainListItem item) {
mDataset.add(position, item);
notifyItemInserted(position);
}
public void remove(MainListItem item) {
int position = mDataset.indexOf(item);
mDataset.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public MainGridAdapter(List<MainListItem> myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public MainGridAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_item_grid_line, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
OnClickListener clickListener = new OnClickListener() {
@Override
public void onClick(View v) {
onItemClicked(position);
}
};
holder.itemView.setOnClickListener(clickListener);
holder.txtHeader.setOnClickListener(clickListener);
holder.txtFooter.setOnClickListener(clickListener);
final MainListItem item = mDataset.get(position);
holder.txtHeader.setText(item.getTitle());
if (TextUtils.isEmpty(item.getDescription())) {
holder.txtFooter.setVisibility(View.GONE);
} else {
holder.txtFooter.setVisibility(View.VISIBLE);
holder.txtFooter.setText(item.getDescription());
}
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.size();
}
public abstract void onItemClicked(int position);
}
在绑定事件中实现单击处理程序,使其只有一个事件实现
执行此:
mAdapter = new MainGridAdapter(listItems) {
@Override
public void onItemClicked(int position) {
showToast("Item Clicked: " + position, ToastPlus.STYLE_INFO);
}
};
同样可以做长时间点击
基于Jacob Tabak的回答(+1),我能够添加onLongClick监听器:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
然后你可以这样使用它:
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
// ...
}
@Override
public void onItemLongClick(View view, int position) {
// ...
}
}));
在ViewHolder中设置点击监听器,如下所示:
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, year, genre;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
genre = (TextView) view.findViewById(R.id.genre);
year = (TextView) view.findViewById(R.id.year);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, ""+getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
}
}
有更简单的方法。只需要在根视图上应用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);
}
}
推荐文章
- 如何在java中格式化持续时间?(如格式H:MM:SS)
- urlencoder .encode(字符串)已弃用,我应该使用什么代替?
- javax.transaction.Transactional vs . org.springframework.transaction.annotation.Transactional
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 改变开关的“开”色
- 以编程方式将EditText的输入类型从PASSWORD更改为NORMAL,反之亦然
- 如何在隐藏和查看密码之间切换
- 在Android上调整一个大的位图文件到缩放输出文件
- 使用Enum实现单例(Java)
- 如何更改Android版本和代码版本号?
- Android Studio突然无法解析符号
- 应用程序重新启动而不是恢复
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?