虽然来晚了,但也许这会帮助其他人。
我找到的将OnClickListener
附加到RecyclerView
中项目或子视图的最佳位置是在RecyclerView.Adapter
的onCreateViewHolder
中。由于RecyclerView
回收/重用项目ViewHolders
,因此创建/附加侦听器的效率最高,因为它们仅在创建新持有者时创建和附加,因此比onBindViewHolder
甚至绑定(在持有者类内部)频繁得多。
但是,需要2-3个东西才能仅注册对特定数据集项的更改(在适配器数据数组/列表中的特定位置的项目)。
如果您有多个ViewHolder类型,并且该信息有助于确定单击时发生的情况,则需要:
ViewHolder
类型或访问Adapter.getViewHolderType()
。
更明显的是,您需要访问单击的数据集(数组/列表)项,以便可以在该项中注册特定于该项的更改(因此当该项滚动屏幕时更改保留在该项中)。这意味着您需要访问:
RecyclerView
的数据集(通常为数组或列表)和
- 数据集中需要更改的特定项目的位置
您还可能需要调用notifyItemChanged()
或notifyItemInserted()
或(效率较低的notifyDataSetChanged()
)
例如,在我的一个项目的适配器中:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == HOLDER_VIEW_TYPE_ONE) {
view = LayoutInflater.from(mContext).inflate(R.layout.type_one_holder_layout, parent, false);
final RecyclerView.ViewHolder holder = new TypeOneHolder(mContext,view);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
final int position = holder.getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
if (mDataList.get(position).getTimeDisplayState() == ON_STATE) {
mMessageList.get(position).setTimeDisplayState(DEFAULT_STATE);
} else {
mMessageList.get(position).setTimeDisplayState(ON_STATE);
}
notifyItemChanged(position);
}
}
});
return holder;
}
}
请注意,我使用这个方法在RecyclerView项被点击时显示和隐藏最后更新时间。timeDisplayState在我的ViewHolder.bind()中进行检查,并且相应地显示时间TextView。
请注意,通过在ViewHolder的构造函数中创建OnClickListener也可以实现相同的结果,因为该构造函数在OnCreateViewHolder()中调用。这样做的好处是适配器可以少做一些工作,并将决策/细节委托给持有者,从而使适配器更简单(代码行数更少)和更通用。缺点是您不能仅创建一个OnClickListener并 indiscriminately 附加到所有Holder类型;您必须在每个viewholder类的构造函数中创建侦听器。不过这并不是一个重大问题。