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

RecyclerView onBindViewHolder中position参数标红求助:提示需使用holder.getAdapterPosition()替代固定position

解决RecyclerView onBindViewHolder中position参数的警告问题

嘿,这个警告我之前也踩过坑!其实它的意思很明确:onBindViewHolder里的position参数只是当前绑定瞬间的位置,不能在后续的异步/回调操作(比如你的点击事件)里直接复用。

为什么会有这个警告?

RecyclerView的Item是复用机制,当列表数据更新、Item被移动/删除,或者列表滚动时,原来的position就不再对应正确的数据了。而点击事件是用户触发的,属于滞后操作,这时候用当初的position去取数据,很可能拿到错误的内容,甚至触发数组越界异常。

你的代码怎么改?

这里有两种靠谱的解决方式:

方式1:用holder.getAdapterPosition()获取实时位置

在点击事件里,不要直接用方法参数里的position,而是调用holder.getAdapterPosition()拿到当前Item的最新位置,记得先判断位置是否有效:

@Override 
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 
    // 这里可以直接用position,因为是立即绑定UI
    Glide.with(context).load(categoryList.get(position).getImg_url()).into(holder.catImg); 
    
    holder.itemView.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View view) { 
            int currentPosition = holder.getAdapterPosition();
            // 先判断位置是否有效,避免无效点击
            if (currentPosition == RecyclerView.NO_POSITION) {
                return;
            }
            Intent intent = new Intent(context, ViewAllActivity.class); 
            intent.putExtra("type", categoryList.get(currentPosition).getType()); 
            context.startActivity(intent); 
        } 
    }); 
}

方式2:直接把数据对象绑定到View的Tag上(更推荐)

这种方式不需要依赖位置,直接把当前Item对应的数据对象存到View的Tag里,点击时直接取出来用,彻底避免位置变化的问题:

// 先假设你的数据类叫CategoryItem,根据实际情况替换
@Override 
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 
    CategoryItem currentItem = categoryList.get(position);
    // 立即绑定UI
    Glide.with(context).load(currentItem.getImg_url()).into(holder.catImg); 
    // 把数据对象设置给View的Tag
    holder.itemView.setTag(currentItem);
    
    holder.itemView.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View view) { 
            CategoryItem clickedItem = (CategoryItem) view.getTag();
            Intent intent = new Intent(context, ViewAllActivity.class); 
            intent.putExtra("type", clickedItem.getType()); 
            context.startActivity(intent); 
        } 
    }); 
}

总结一下

  • onBindViewHolder的position参数只适合在方法执行的当下立即使用(比如绑定UI);
  • 任何延迟执行的操作(点击、异步回调等),要么用holder.getAdapterPosition()获取实时位置,要么直接持有对应的数据对象;
  • 第二种方式(存Tag)更稳妥,因为它完全脱离了对位置的依赖,避免了各种边界情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:42:29