遇到奇怪Bug:RecyclerView滚动时EditText内容自动填充该如何解决?
问题根因
这个问题是RecyclerView的item复用机制+EditText默认开启视图状态保存逻辑共同导致的:
RecyclerView滚动时会复用滑出屏幕的item视图,而EditText默认开启了
saveEnabled属性,系统会自动为同ID的EditText恢复之前保存的输入内容,即便你把onBindViewHolder逻辑置空,系统层面的状态恢复逻辑还是会执行,就会出现内容自动填充/串位的问题。
可行解决方案
方案1:直接关闭EditText的状态保存能力
可以在布局XML中给EditText添加属性:android:saveEnabled="false"也可以在代码中动态设置:
editText.setSaveEnabled(false);这个方案最简单直接,适合不需要系统保存EditText输入状态的场景。
方案2:onBindViewHolder中先清理监听再重置内容
你之前置空onBindViewHolder没有生效,大概率是没有提前移除EditText绑定的旧TextWatcher,正确的绑定逻辑如下:@Override public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) { // 第一步:移除之前绑定的文本监听,避免清空内容时触发旧逻辑 if (holder.inputEt.getTag() instanceof TextWatcher) { holder.inputEt.removeTextChangedListener((TextWatcher) holder.inputEt.getTag()); } // 第二步:主动清空EditText现有内容 holder.inputEt.setText(""); // 第三步:添加当前item对应的业务逻辑、绑定新的监听 TextWatcher currentWatcher = 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) { // 把输入内容存入对应position的数据源,不要存在ViewHolder里 dataList.get(position).setInputContent(s.toString()); } }; holder.inputEt.addTextChangedListener(currentWatcher); holder.inputEt.setTag(currentWatcher); // 如果当前position已有保存的输入内容,主动赋值 holder.inputEt.setText(dataList.get(position).getInputContent()); }方案3:为每个EditText绑定唯一标识避免ID冲突
如果你的列表项存在多个EditText,可以在绑定的时候给每个EditText设置和当前position关联的唯一Tag,读取输入内容时通过Tag匹配对应的数据源位置,避免内容串位。
不推荐的解决方案
不要为了规避复用问题给ViewHolder设置setIsRecyclable(false),这个会完全关闭RecyclerView的复用机制,列表数据量稍大就会出现卡顿、内存飙升的问题。
内容的提问来源于stack exchange,提问作者Aniket Verma
相关产品推荐
相关产品推荐

