我正在尝试创建一个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.out:0 <-正确
之后:et0更改= I / System.out:2 AND I / System.out:0 <-错误
答案 0 :(得分:3)
之所以发生这种情况,是因为每次将ViewHolder与视图绑定时,您都会添加一个新的TextWatcher。 RecyclerView正确地回收了ViewHolders,因此当它使用已经创建的ViewHolders时,它只会添加一个新的TextWatcher。
您可以通过在创建ViewHolder时注册TextWatcher来修改使用此方法的方式,因此您不必处理continuos侦听器绑定。因此,在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);
}
请随时询问是否不清楚。