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

RecyclerView滚动后数据丢失问题求助(适配Android 11/12/13)

解决RecyclerView滚动数据丢失/错位问题(Android 12/13)

核心问题根源

你遇到的问题本质是RecyclerView的ViewHolder复用机制与Adapter绑定逻辑不匹配。低版本Android的RecyclerView复用策略相对宽松,没暴露逻辑漏洞;但Android 12/13对复用机制做了优化,更频繁地复用ViewHolder,直接放大了“UI状态未与数据源同步”的问题。之前尝试的setHasStableIds(true)、禁用复用等方法都是治标不治本,核心要修正Adapter的绑定逻辑。

必须执行的修复步骤

1. 强制UI状态完全依赖数据源

所有条目的数据(包括用户输入的内容)必须实时同步到你的数据集(比如List<YourDataModel>),不能只存放在ViewHolder的EditText/TextView等视图中。

  • 示例:用户在EditText输入时,通过TextWatcher把输入值同步到对应的数据模型:
    holder.inputEt.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {}
        @Override
        public void afterTextChanged(Editable s) {
            // 直接更新数据源对应位置的字段
            mDataList.get(holder.getAdapterPosition()).setInputContent(s.toString());
        }
    });
    

2. 所有UI绑定逻辑必须放在onBindViewHolder中

不要在onCreateViewHolder中设置与数据相关的内容或监听,所有条目级的UI赋值、事件监听都要在onBindViewHolder中完成,且每次绑定都要覆盖旧状态:

  • 错误示例:只在onCreateViewHolder中给EditText设置初始值,复用ViewHolder时不会更新为最新数据。
  • 正确示例:
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        YourDataModel item = mDataList.get(position);
        // 每次绑定都重新设置文本,覆盖复用带来的旧数据
        holder.inputEt.setText(item.getInputContent());
        
        // 注意:绑定监听前要先移除旧监听,避免重复触发
        holder.inputEt.removeTextChangedListener(holder.textWatcher);
        holder.textWatcher = new TextWatcher() {
            // 实现监听逻辑,同步数据源
        };
        holder.inputEt.addTextChangedListener(holder.textWatcher);
    }
    

3. 正确使用通知更新方法

修改数据源后,必须调用对应的notifyXXX方法通知Adapter更新,禁止直接操作ViewHolder视图:

  • 添加条目:notifyItemInserted(position)
  • 修改条目:notifyItemChanged(position)
  • 避免使用notifyDataSetChanged()(全量更新效率极低,且可能引发额外复用问题)

4. 禁用错误的“规避复用”操作

holder.setIsRecyclable(false)会完全禁用ViewHolder复用,导致内存占用飙升,高版本系统下可能触发内存警告甚至崩溃,绝对不能用。setHasStableIds(true)仅当你的数据有唯一且永不改变的ID时才有用,否则只会增加额外开销。

针对Android 12/13的额外检查

高版本系统中,RecyclerView的RecycledViewPool会更高效地复用ViewHolder,需确保:

  • 数据模型类的equals/hashCode方法正确实现(如果用到DiffUtil的话)
  • 不要在Adapter之外保存ViewHolder的引用,避免外部修改UI导致状态混乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 17:52:24