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
相关产品推荐
相关产品推荐

