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

RecyclerView中EditText滚动丢失内容/位置错乱的解决方法咨询

解决RecyclerView中EditText滚动内容清空/错乱的问题

这个问题我太熟了——完全是RecyclerView的ViewHolder复用机制在搞事情!当列表滚动时,滑出屏幕的ViewHolder会被重新拿来显示新的列表项,如果你的EditText内容没有和数据源绑定,就会出现内容丢失或者跑到其他项里的情况。下面给你一步步解决的方案:

1. 给数据源类添加存储EditText内容的字段

首先确保你的Voltage类有两个字段,用来对应每个列表项里两个EditText的内容,这样每个项的输入都能存在自己的数据源对象里:

public class Voltage {
    // 保留你原来的其他字段
    private String input1; // 对应第一个EditText的内容
    private String input2; // 对应第二个EditText的内容

    // 添加getter和setter方法
    public String getInput1() {
        return input1;
    }

    public void setInput1(String input1) {
        this.input1 = input1;
    }

    public String getInput2() {
        return input2;
    }

    public void setInput2(String input2) {
        this.input2 = input2;
    }
}

2. 修改ViewHolder,保存TextWatcher引用

因为ViewHolder会被复用,我们需要在ViewHolder里保存每个EditText的TextWatcher引用,这样下次绑定的时候可以先移除旧的监听,避免重复触发:

public static class DataViewHolder extends RecyclerView.ViewHolder {
    EditText editText1;
    EditText editText2;
    // 保存TextWatcher的引用,用于复用前移除监听
    TextWatcher textWatcher1;
    TextWatcher textWatcher2;

    public DataViewHolder(@NonNull View itemView) {
        super(itemView);
        // 替换成你实际的EditText ID
        editText1 = itemView.findViewById(R.id.et_input1);
        editText2 = itemView.findViewById(R.id.et_input2);
    }
}

3. 在onBindViewHolder中绑定数据+监听输入

这是最关键的一步:每次绑定ViewHolder时,先从数据源读取内容设置给EditText,然后添加TextWatcher把输入内容同步回数据源,同时要先移除旧的监听:

@Override
public void onBindViewHolder(@NonNull DataViewHolder holder, int position) {
    Voltage currentVoltage = datas.get(position);

    // 从数据源读取内容,设置给EditText
    holder.editText1.setText(currentVoltage.getInput1());
    holder.editText2.setText(currentVoltage.getInput2());

    // 先移除旧的TextWatcher,防止复用导致的多次绑定
    holder.editText1.removeTextChangedListener(holder.textWatcher1);
    holder.editText2.removeTextChangedListener(holder.textWatcher2);

    // 为第一个EditText创建新的监听,同步输入到数据源
    holder.textWatcher1 = 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) {
            // 把输入内容保存到当前的Voltage对象里
            currentVoltage.setInput1(s.toString());
        }
    };

    // 第二个EditText同理
    holder.textWatcher2 = 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) {
            currentVoltage.setInput2(s.toString());
        }
    };

    // 添加新的TextWatcher到EditText
    holder.editText1.addTextChangedListener(holder.textWatcher1);
    holder.editText2.addTextChangedListener(holder.textWatcher2);
}

额外注意点

  • 当你点击按钮添加新项时,要创建新的Voltage对象并添加到datas列表,然后调用notifyItemInserted(datas.size() - 1),这样新项有自己的数据源来存储输入内容。
  • 如果你的列表有增删操作,尽量用holder.getAdapterPosition()来获取当前项的位置,避免直接用position(因为position是绑定瞬间的位置,数据源变化后可能失效)。

这样修改后,滚动RecyclerView时,每个EditText的内容都会和对应的数据源对象绑定,再也不会出现内容清空或者错乱的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:26:23