【问题标题】:RecyclerView .addTextChangedListener gives multiple positionsRecyclerView .addTextChangedListener 给出多个位置
【发布时间】:2019-06-11 13:58:51
【问题描述】:

我正在尝试创建一个 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

【问题讨论】:

  • 不要使用位置变量,使用holder.getAdapterPosition();方法获取位置。
  • 您要打印上次修改的EditText 的数据,我理解正确吗?
  • @JeelVankhede 它确实将位置固定为正确的值,但现在它总是打印两次相同的位置。
  • @DawidJ 最终是的,但现在我只需要 EditText 的位置。

标签: java android android-recyclerview notifydatasetchanged addtextchangedlistener


【解决方案1】:

发生这种情况是因为每次 ViewHolder 与视图绑定时,您都会添加一个新的 TextWatcher。 RecyclerView 正确地回收了 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);
}

如果有任何不清楚的地方,请随时询问。

【讨论】:

  • 这是一个绝妙的答案,并且使用标签能够引用适配器中的位置的解释是额外的奖励。
猜你喜欢
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 2017-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多