有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
这个作品。
public class ServiceListAdapter extends RecyclerView.Adapter<ServiceListAdapter.ViewHolder> {
private final Context mContext;
private List<ServiceListModel> categoryList;
private View.OnClickListener onClickListener;
public ServiceListAdapter(Context mContext, List<ServiceListModel> categoryList, View.OnClickListener onClickListener) {
this.categoryList = categoryList;
this.mContext = mContext;
this.onClickListener = onClickListener;
}
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
final RowServiceListBinding binding = DataBindingUtil.inflate(inflater, R.layout.row_service_list, parent, false);
return new ViewHolder(binding.getRoot(), binding);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.binding.rlService.setOnClickListener(onClickListener);
holder.binding.rlService.setTag(position);
}
@Override
public int getItemCount() {
return categoryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private final RowServiceListBinding binding;
public ViewHolder(final View view, final RowServiceListBinding binding) {
super(view);
this.binding = binding;
}
@UiThread
public void bind(final ServiceListModel mAddressModel) {
//this.binding.setAddress(mAddressModel);
}
}
}
在活动/片段中使用
ServiceListAdapter adapter = new ServiceListAdapter(context, serviceList, new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rlService:
int pos = (int) v.getTag();
serviceList.remove(position);
break;
}
}
});
其他回答
让我们看看如何在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));
});
以下是我所做的。这个解决方案同时支持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()也被调用(当点击图像)。
试试这个,很简单。这对我很管用。顺便说一句,我发现setOnClickListener对RecyclerView不生效。
recycler.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
// anything todo
}
return true;
}
});
你可以很容易地在ViewHolder类中定义setOnClickListener,如下所示:
public class ViewHolder extends RecyclerView.ViewHolder {
TextView product_name;
ViewHolder(View itemView) {
super(itemView);
product_name = (TextView) itemView.findViewById(R.id.product_name);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int itemPosition = getLayoutPosition();
Toast.makeText(getApplicationContext(), itemPosition + ":" + String.valueOf(product_name.getText()), Toast.LENGTH_SHORT).show();
}
});
}
}
对我来说,这是最好的方法:
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
}
...
}