有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
这对我来说很难在活动中有一个项目点击监听器,也有一个项目的单一视图的点击监听器,不会触发项目点击监听器。在玩了Jacob Tabak的回答后,我尊重他的回答,如果项目内没有其他触摸操作,就点击项目。
我有一个自定义OnClickListener接口,有一个项目点击事件,它持有从适配器点击的项目的视图和项目的位置。我在构造函数(或者它可以是setter)中呈现它的一个实例,并将它附加到视图持有者容器click listener。
我也有其他的点击监听器在适配器(可以在视图持有人),这将处理当前的视图点击从容器。
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {
private ArrayList<String> mData;
private OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
public MyRecyclerAdapter(ArrayList<String> itemsData,
OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
this.mData = itemsData;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View layoutView = LayoutInflater.from(mContext).inflate(
R.layout.list_item, parent, false);
final MyViewHolder viewHolder = new MyViewHolder(layoutView);
viewHolder.container.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(v, viewHolder.getAdapterPosition());
}
});
viewHоlder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//do button click work here with
// mData.get( viewHolder.getAdapterPosition() );
}
});
return viewHolder;
}
@Override
public int getItemCount() {
return mData.size();
}}
在活动中,您需要通过传递OnItemClickListener实例来初始化适配器
public class FeedActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
.....
MyRecyclerAdapter adapter = new MyRecyclerAdapter(new ArrayList<String>(), new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
///list item was clicked
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mFeedsAdapter);
}
还有我的ViewHolder
public class MyViewHolder extends RecyclerView.ViewHolder {
public Button button;
public View container;
public MyViewHolder(View itemLayoutView) {
super(itemLayoutView);
container = itemLayoutView;
button = (Button) itemLayoutView.findViewById(R.id.button);
}}
其他回答
这里有一个简单明了的方法是添加到您的ReacyclerView ViewHolder
public static class MyViewholder extends RecyclerView.ViewHolder {
public MyViewholder(View itemView) {
super(itemView);
itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Tag", "onClick:" + getAdapterPosition());
}
});
}
}
getAdapterPosition()返回当前被单击项的位置
这里有一个更好的和不那么紧密耦合的方式来实现一个OnClickListener的RecyclerView。
用法片段:
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
// do whatever
}
@Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
RecyclerItemClickListener实现:
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 {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
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 child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@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 true;
}
return false;
}
@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
查看类似的问题@CommonsWare的评论链接到this,它在viewHolder中实现了OnClickListener接口。
下面是ViewHolder的一个简单例子:
/** Declare global with in adapter class. */
TextView textView;
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView) view.findViewById(android.R.id.text1);
}
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
/** Go through each item if you have few items within RecyclerView. */
if (getLayoutPosition() == 0) {
// Do whatever you want here
} else if(getLayoutPosition() == 1) {
// Do whatever you want here
} else if(getLayoutPosition() == 2) {
// Do whatever you want here
}
/** Or you can use For loop if you have long list of items. */
for (int i = 0; i < exampleList.size(); i++) {
// Do whatever you want here
}
}
}
在你的RecyclerView中创建ViewHolder。适配器看起来像这样:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext())
View view = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
}
在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();
}
});
}
}
让我们看看如何在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));
});
推荐文章
- 如何在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中已弃用?