gpt4 book ai didi

android - RecyclerView - 未调用 onBindViewHolder 时,findViewHolderForPosition 始终返回 null

转载 作者:太空宇宙 更新时间:2023-11-03 13:20:10 26 4
gpt4 key购买 nike

我一直在尝试使用新的 RecyclerView小部件几天了,我认为我已经设法创建了水平和网格布局,并且还克服了它缺乏实现 OnClickListener 的直接方法的事实(我为此使用了 GreenRobot's EventBus),我仍然很难选择一件元素并在整个回收过程中保持该状态(风格)。

这是我用于我的适配器的代码

public class ArticuloItemAdapter extends RecyclerView.Adapter<ArticuloItemAdapter.ItemHolder> {
private ArrayList<ArticuloObject> mItems;
private LayoutInflater mLayoutInflater;
private int mSize;
private int mSelectedPosition;
private RecyclerView mRecyclerView;

public ArticuloItemAdapter(Context context, RecyclerView rv, ArrayList<ArticuloObject> articulos) {

mLayoutInflater = LayoutInflater.from(context);
mItems=articulos ;
mSize = context.getResources()
.getDimensionPixelSize(R.dimen.icon);
mSelectedPosition = -1;
mRecyclerView = rv;
}

@Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mLayoutInflater.inflate(R.layout.gallery_recycler_row, parent, false);
return new ItemHolder(itemView, this);
}

@Override
public void onBindViewHolder(ItemHolder holder, int position) {
Ion.with(holder.getPicImageView())
.placeholder(R.drawable.owner_placeholder)
.resize(mSize, mSize)
.centerCrop()
.error(R.drawable.owner_error)
.load(mItems.get(position).getUrl());

//Update the views as they got recycled
if (mSelectedPosition != position) {
holder.getPicImageView().setBackgroundColor(Color.TRANSPARENT);
} else {
holder.getPicImageView().setBackgroundColor(Color.CYAN);
}
}

@Override
public int getItemCount() {
return mItems.size();
}

public int getSelectedPosition() {
return mSelectedPosition;
}

public void setSelectedPosition(int mSelectedPosition) {
this.mSelectedPosition = mSelectedPosition;
}

public RecyclerView getRecyclerView() {
return mRecyclerView;
}

/* Required implementation of ViewHolder to wrap item view */
public class ItemHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
private ArticuloItemAdapter mParent;
private ImageView mPicImageView;

public ItemHolder(View itemView, ArticuloItemAdapter parent) {
super(itemView);
itemView.setOnClickListener(this);

mParent = parent;

mPicImageView = (ImageView) itemView.findViewById(R.id.picture_image_view);
}

public ImageView getPicImageView() {
return mPicImageView;
}

@Override
public void onClick(View v) {
EventBus.getDefault().post(new OnArticuloCartaClickEvent(this, getPosition()));
setItemActivated(v);
}

public void setItemActivated(View v) {

//Check position of previous selected item. The first time an item is selected, the previous position will be -1
if (mParent.getSelectedPosition() >= 0) {
ItemHolder row = (ItemHolder) mParent.getRecyclerView().findViewHolderForPosition(mParent.getSelectedPosition());
if (row != null) {
row.getPicImageView().setBackgroundColor(Color.TRANSPARENT);
}
}
mParent.setSelectedPosition(getPosition());
v.findViewById(R.id.picture_image_view).setBackgroundColor(Color.CYAN);

}
}

}

现在在上面显示的代码中,我为跟踪所选项目所做的一切如下:

我。在 onClick(View v) 事件中:

  1. 每当单击某个项目时,我都会调用 setItemActivated 方法
  2. 在 setItemActivated 方法中,我检查 selectedPosition 是否大于或等于 0(当未选择任何项目时,默认值为 -1)。
  3. 如果前面的条件为真,我尝试在该位置获取 ViewHolder,如果该 View 不为空,我将 ImageView 的背景颜色更改回它是原始背景颜色(透明)
  4. 使用 getPosition()
  5. 将 mSelectedPosition 的新值设置为当前位置
  6. 最后,将当前 ViewHolder 中的 ImageView 的背景颜色更改为不同的颜色(在本例中为青色)

二。在 onBindViewHolder(ItemHolder holder, int position) 方法中:

如果所选项目的位置 (mSelectedPosition) 不同于正在显示的 View 的位置,我更改背景ImageView 的颜色恢复为默认颜色。否则,我将 ImageView 的颜色更改为用于标识所选项目的颜色 (CYAN)。

只要 RecyclerView 有相当多的项目需要开始回收 View ,所有这一切都有效。但如果没有,就像我的情况一样,我注意到 findViewHolderForPosition 总是返回 null,因此,我无法将先前选择的项目的颜色更改回其默认颜色并且所以我最终选择了不止一项。

enter image description here

更糟糕的是,由于 RecyclerView 不需要回收任何东西,onBindViewHolder 方法永远不会被调用,因此我不能指望代码里面相应地调整项目的颜色。

拜托,如果有人能告诉我我在这里做错了什么或者提供一些想法,我将不胜感激。不能做像选择项目这样基本的事情真的很令人沮丧。

提前致谢。

最佳答案

发生这种情况是因为当所选项目发生变化时,您并没有告诉 RecyclerView 之前的项目已失效。

与其尝试手动设置,不如执行以下操作:

public void setItemActivated(View v) {
final int myPos = getAdapterPosition();
if (myPos == RecyclerView.NO_POSITION) {
// very rare case where item is clicked but its adapter position
// is unknown. ignore the event.
// See docs of getAdapterPosition for details
}
final int prevSelected = mParent.getSelectedPosition();
mParent.setSelectedPosition(myPos);
if (prevSelected >= 0 && prevSelected < mParent.getItemCount()) {
mParent.notifyItemChanged(prevSelected);
}
mParent.notifyItemChanged(myPos);
}

RecyclerView 将为应该更新的 View 调用 onBind。你不需要关心之前选择的项目在哪里。

关于android - RecyclerView - 未调用 onBindViewHolder 时,findViewHolderForPosition 始终返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29458808/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com