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

RecyclerView滚动后Item内容变更问题求助

这问题我太熟了!RecyclerView的复用机制搞的鬼,我当初刚学的时候也踩过这个坑😅

问题根源

RecyclerView为了性能会复用滚出屏幕的ViewHolder,如果你在绑定数据时没有完全覆盖所有控件的内容,旧Item的内容就会残留到新复用的Item上。硬编码时你给每个Item都写死了固定内容,自然不会有问题;但改成从strings.xml取数据后,大概率是onBindViewHolder方法里的逻辑有遗漏,导致复用后没有正确替换内容。

分步解决方案

1. 检查onBindViewHolder方法(最关键)

确保每个position对应的所有UI控件都被赋值,不要用if-else只给特定position设置内容,要直接通过数据集合对应位置取值:

错误示例(容易踩坑):

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    if (position == 0) {
        holder.tvItem.setText(getString(R.string.item1));
    } else if (position == 1) {
        holder.tvItem.setText(getString(R.string.item2));
    }
    // 超过position=2的Item会复用旧ViewHolder,显示之前的内容
}

正确写法:
先把strings.xml里的资源ID存成数组/列表,然后直接根据position取值:

// 定义字符串资源ID数组
private int[] itemStringIds = {
        R.string.item1, R.string.item2, R.string.item3,
        R.string.item4, R.string.item5, R.string.item6
};

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    // 不管position是多少,都覆盖设置对应文本
    String content = holder.itemView.getContext().getString(itemStringIds[position]);
    holder.tvItem.setText(content);
    
    // 如果还有其他控件(比如ImageView、CheckBox),也要同步设置对应数据,不要遗漏
    // holder.ivIcon.setImageResource(iconIds[position]);
}

2. 确保getItemCount返回正确数量

检查Adapter的getItemCount方法,返回值必须和你的Item总数一致(也就是6):

@Override
public int getItemCount() {
    return itemStringIds.length; // 直接返回数组长度,避免手动写死数字出错
}

3. 不要在ViewHolder构造函数里设置动态内容

ViewHolder只负责初始化控件引用,所有动态内容(文本、图片、状态)都要放在onBindViewHolder里设置:

static class MyViewHolder extends RecyclerView.ViewHolder {
    TextView tvItem;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        tvItem = itemView.findViewById(R.id.tv_item);
        // ❌ 不要在这里设置setText,所有动态内容交给onBindViewHolder
    }
}

4. 处理带状态的Item(如果有的话)

如果你的Item有选中、展开这类动态状态,一定要把状态存在数据模型里,而不是ViewHolder中。比如CheckBox的选中状态,要在onBindViewHolder里根据数据模型设置,否则复用后会保留旧状态。

完整Adapter示例参考

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private int[] mItemStringIds;

    public MyAdapter(int[] itemStringIds) {
        mItemStringIds = itemStringIds;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_layout, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        // 核心:每次绑定都覆盖设置内容
        String text = holder.itemView.getContext().getString(mItemStringIds[position]);
        holder.tvItem.setText(text);
    }

    @Override
    public int getItemCount() {
        return mItemStringIds != null ? mItemStringIds.length : 0;
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvItem;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvItem = itemView.findViewById(R.id.tv_item);
        }
    }
}

按照上面的步骤检查你的代码,大概率就能解决滚动后内容错乱的问题了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:10:57