RecyclerView .addTextChangedListener 给出多个位置

RecyclerView .addTextChangedListener gives multiple positions

我正在尝试创建一个 RecyclerView,它在每一行中都包含一个 EditText。 更改文本后,我希望它用 println 显示位置。 它 运行 很好,直到我在我的主要方法中 运行 .notifyDataSetChanged() 。 之后它会打印多个位置,即使只更改了一个 EditText。

@Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        holder.etName.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

           }
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
            @Override
            public void afterTextChanged(Editable editable) {
                System.out.println(position);
            }
        });
}

之前:et0 已更改 = I/System。输出:0 <- 正确

after: et0 changed = I/System.out: 2 AND I/System.out: 0 <- wrong

发生这种情况是因为您每次将 ViewHolder 与视图绑定时都会添加一个新的 TextWatcher。 RecyclerView 正确地回收了 ViewHolders,所以当它使用一个已经创建的 ViewHolders 时,它只是添加一个新的 TextWatcher。

您可以通过在创建 ViewHolder 时注册 TextWatcher 来修改您的使用方式,这样您就不必处理连续的侦听器绑定。因此,在您的 ViewHolder 构造函数中,在绑定 EditText 之后,您可以添加 TextWatcher,如下所示:

this.etName = root.findViewById(R.id.yourEtID); // I'm sure you're doing something very similar to this in your VH's constructor
this.etName.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

       }
        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }
        @Override
        public void afterTextChanged(Editable editable) {
            System.out.println(etName.getTag());
        }
    });

您会注意到,这次我使用了 etName.getTag() 来读取位置。这非常有用,因为现在您只需将 onBindViewHolder 修改为如下所示:

@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
    holder.etName.setTag(position);
}

有什么不明白的就尽管问。