You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView编辑列表项时getAdapterPosition()触发ArrayIndexOutOfBounds异常

解决RecyclerView编辑列表项时的ArrayIndexOutOfBounds异常

嘿,咱们来搞定你遇到的这个RecyclerView数组越界问题!你怀疑getAdapterPosition()是问题根源,这点完全没错——这确实是这类bug的高发区。

为啥会出问题?

RecyclerView的ViewHolder会被复用,当你触发编辑操作时,如果对应的视图已经被回收,或者列表数据已经发生了更新(比如删了某一项、移动了位置),getAdapterPosition()可能会返回RecyclerView.NO_POSITION(也就是-1),或者返回一个过时的位置索引。用这个无效索引去操作数据集合,自然就会抛出数组越界异常。

具体修复方案

1. 先检查位置是否有效

在调用editClassnameAt()之前,一定要先判断位置是不是合法的:

int position = holder.getAdapterPosition();
if (position == RecyclerView.NO_POSITION) {
    // 位置无效,直接返回,别往下走了
    return;
}
// 确认没问题再执行编辑
editClassnameAt(position, newClassName);

2. 改用getBindingAdapterPosition()(更靠谱)

如果你用的是AndroidX版本的RecyclerView(现在基本都是),getAdapterPosition()已经被标记为过时了,推荐用getBindingAdapterPosition()替代。它能更精准地返回当前ViewHolder在绑定的Adapter中的位置,尤其是在使用ConcatAdapter这类多Adapter组合的场景下,能避免位置混淆:

int position = holder.getBindingAdapterPosition();
if (position == RecyclerView.NO_POSITION) {
    return;
}
editClassnameAt(position, newClassName);

3. 给editClassnameAt()加个安全防护

也有可能你的editClassnameAt()方法本身没做边界检查,直接就去访问数据集合了,比如这样:

// 错误示例:没检查position是否在有效范围内
public void editClassnameAt(int position, String newName) {
    mClassNames.get(position).setName(newName); // 这里直接访问,很容易越界
    notifyItemChanged(position);
}

// 修复后:加上边界校验
public void editClassnameAt(int position, String newName) {
    if (position < 0 || position >= mClassNames.size()) {
        Log.w(TAG, "无效的位置索引: " + position);
        return;
    }
    mClassNames.get(position).setName(newName);
    notifyItemChanged(position);
}

4. 异步场景别依赖位置(比如弹窗编辑)

如果你的编辑操作是异步触发的——比如弹出一个输入Dialog,用户输入完才执行编辑——这时候ViewHolder可能已经被复用,位置早就失效了。这种情况最好在触发编辑时,保存当前数据项的唯一标识(比如item的ID),而不是依赖位置:

// 假设你的数据模型有唯一ID字段
public class ClassItem {
    private String id;
    private String className;
    // getter、setter方法
}

// 点击编辑按钮时,先拿到当前item的ID
holder.editBtn.setOnClickListener(v -> {
    int position = holder.getBindingAdapterPosition();
    if (position != RecyclerView.NO_POSITION) {
        ClassItem currentItem = mClassNames.get(position);
        showEditDialog(currentItem.getId());
    }
});

// 当用户确认编辑后,通过ID找到对应的位置再更新
private void onEditConfirm(String itemId, String newClassName) {
    for (int i = 0; i < mClassNames.size(); i++) {
        if (mClassNames.get(i).getId().equals(itemId)) {
            mClassNames.get(i).setClassName(newClassName);
            notifyItemChanged(i);
            break;
        }
    }
}

总结

按照上面的步骤来:先确保获取的位置有效,改用更靠谱的getBindingAdapterPosition(),给editClassnameAt()加边界检查,异步场景用唯一ID定位——基本上就能解决这个数组越界的问题了!

内容的提问来源于stack exchange,提问作者Aham_Uzoma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:07:02