ViewHolder 中的 onClick 无权访问适配器中的单击项目
Posted
技术标签:
【中文标题】ViewHolder 中的 onClick 无权访问适配器中的单击项目【英文标题】:onClick inside ViewHolder doesn't have access to clicked item in adapter 【发布时间】:2017-01-22 09:37:31 【问题描述】:1) 问题
我想在 CardView 内的 2 个按钮上设置 2 个侦听器。我需要知道选择了哪个项目。我将 CardView 与 RecyclerView 和 FirebaseRecyclerAdapter (RecyclerView.Adapter) 一起使用
2) 旧情况
我在 FirebaseRecyclerAdapter 的 populateViewHolder() 中创建了监听器,如下所示:
@Override
protected void populateViewHolder(final ItemViewHolder viewHolder, final Item model, final int position)
viewHolder.firstButton.setOnClickListener(new View.OnClickListener()
Item selectedItem = getItem(position);
//do something for the item selected
这很好用!
3) 我想做的事
在 ViewHolder 类中设置监听器(在他自己的文件中定义)并对选中的 ITEM 做一些事情
我想在 ViewHolder 类中设置监听器,因为相同的 ViewHolder 用于不同的适配器,我认为将监听器的行为只定义在一个地方是一种更好的方法。
我是这样做的:
public class ItemViewHolder extends RecyclerView.ViewHolder
public CardView cardView;
public TextView itemText;
public ImageView itemFirstButton;
public ImageView itemSecondButton;
public ItemViewHolder(View itemView)
super(itemView);
cardView = (CardView)itemView.findViewById(R.id.item_card_view);
itemText = (TextView)itemView.findViewById(R.id.item_text);
itemFirstButton = (ImageView)itemView.findViewById(R.id.ic_first_action);
itemSecondButton = (ImageView)itemView.findViewById(R.id.ic_second_action);
itemFirstButton.setOnClickListener(firstListener);
itemSecondButton.setOnClickListener(secondListener);
private View.OnClickListener firstLinstener = new View.OnClickListener()
@Override
public void onClick(View v)
int position = getAdapterPosition();
;
private View.OnClickListener secondListener = new View.OnClickListener()
@Override
public void onClick(View v)
int position = getAdapterPosition();
;
在侦听器内部,我无法获得有关该项目的任何参考,只有位置...
我的印象是我必须为侦听器声明一个接口并传递给适配器,但我不知道如何。
在视图中声明侦听器是否仍然有意义,或者我将它们作为旧解决方案保留在适配器中?
【问题讨论】:
没有。当您需要来自适配器的东西时,将侦听器放在 ViewHolder 中对我来说没有意义。由于视图在滚动过程中不断被销毁和重新创建,因此您需要在 onBind 期间对其进行定义。如果你的监听器做了一些通用的事情并且不依赖于任何适配器数据,那么将它放在 viewHolder 中是有意义的。 嗨,Panther,我的听众做了一些依赖于项目的事情(例如单击我想共享项目数据的按钮)。共享操作对于使用相同 ViewHolder 的 2 个不同适配器具有相同的行为。因此,如果我很好理解,您建议将侦听器保留在适配器内... 是的,我建议您将监听器保留在适配器内。但是,由于您提到操作是相同的,我相信您正在尝试找到一个 DRY 解决方案。在您的情况下,我会做的是编写一个通用函数来执行所有共享。侦听器只是一个代理,它将使用适当的数据调用共享操作。 【参考方案1】:如果你想告诉适配器你的位置,只需通过 ViewHolder 构造函数传递一些接口。 要么 以前的方式。
关键是您要将职位委派给谁。
【讨论】:
【参考方案2】:是的,使用界面是个好习惯。创建一个类似
的界面public interface OnClick
void getItem(int item);
然后setOnClicklistner就好了
itemViewHolder. itemText.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
OnClick onClick = (OnClick)context;
onClick.getItem(position);
);
然后在您的活动中实现该方法。从这里你得到位置。然后通过使用位置从数组中获取元素。
【讨论】:
您好,感谢您的回答……抱歉,我不太清楚该怎么做。我必须在适配器上设置监听器吗?假设我想在 ViewHolder 中定义一个侦听器,该侦听器能够实现共享操作以共享所选项目数据(因此应在 ViewHolder 中定义 onClick 行为)。如何将项目从适配器传递到 ViewHolder?以上是关于ViewHolder 中的 onClick 无权访问适配器中的单击项目的主要内容,如果未能解决你的问题,请参考以下文章
在Android Kotlin中,将onclick事件传递给viewholder的正确方法是啥?
在 RecyclerView 适配器中初始化 viewHolder 时出错