android 棉绒错误“不要将位置视为固定;只能立即使用...”

jw5wzhpr  于 2023-02-14  发布在  Android
关注(0)|答案(2)|浏览(103)

我正在为开源库做贡献,但遇到了lint错误**“不要将位置视为固定;仅立即使用并调用保持器.getAdapterPosition()稍后查找”**对于此代码:

@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    mAdapter.onBindViewHolder(holder, position);

    if (!isFirstOnly || position > mLastPosition) {
      for (Animator anim : getAnimators(holder.itemView)) {
        anim.setDuration(mDuration).start();
        anim.setInterpolator(mInterpolator);
      }
      mLastPosition = position;
    } else {
      ViewHelper.clear(holder.itemView);
    }
  }

我已经检查了这是因为位置被保存以备将来使用。这是一个库创建者为什么需要这个逻辑的问题。但是当我将位置的用法更改为用法holder.getAdapterPosition()时,问题消失了:

@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    mAdapter.onBindViewHolder(holder, position);

    if (!isFirstOnly || holder.getAdapterPosition() > mLastPosition) {
      for (Animator anim : getAnimators(holder.itemView)) {
        anim.setDuration(mDuration).start();
        anim.setInterpolator(mInterpolator);
      }
      mLastPosition = holder.getAdapterPosition();
    } else {
      ViewHelper.clear(holder.itemView);
    }
  }

我假设概念上它没有太大变化,但是lint现在满足了。为什么?

q3qa4bjr

q3qa4bjr1#

RecyclerView.Adapter.onBindViewHolder()的文档声明:
注意,与ListView不同的是,如果项在数据集中的位置发生变化,RecyclerView不会再次调用此方法,除非项本身无效或无法确定新的位置。为此,您应该只在获取此方法中的相关数据项时使用position参数,而不应保留它的副本。如果您以后需要某项的位置(例如,在click侦听器中),使用getAdapterPosition(),它将具有更新的适配器位置
因此,技术上来说,项目可能会重新安排(比如排序或移动)和绑定都是不必要的,因为项目还没有失效。这意味着如果项目显示相同的数据,则不需要调用onBindViewHolder()。而只是它们在列表中的位置/索引改变。收到的position变量仅在绑定函数的作用域中为真,并且不会始终指向数据集中的正确位置。这就是为什么每次需要更新位置时必须调用函数getAdapterPosition()的原因。
恕我直言,mLastPosition = holder.getAdapterPosition();仍然是潜在的错误。因为项目可能会被重新安排,mLastPosition仍然指向旧的位置。
关于为什么lint是静默的,也许Lint的规则并没有那么彻底,它只是检查position参数是否被复制。

nx7onnlm

nx7onnlm2#

我的旧代码:

@Override

//here int position gave a error

public void onBindViewHolder(@NonNull CartListAdapator.ViewHolder holder, int position) {

    holder.titleTxt.setText(foodDomains.get(position).getTitle());
    holder.feeEachItem.setText(String.valueOf(foodDomains.get(position).getFee()));

    
    holder.plusItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            managementCart.plusNumberFood(foodDomains, position, new ChangeNumberItemListener() {
                @Override
                public void changed() {
                    notifyDataSetChanged();
                    changeNumberItemListener.changed();
                }
            });
        }
    });

因此,在plusNumberFood()方法中,我更改了参数position -〉保持器.getAdapterPosition();
验证码:

@Override
public void onBindViewHolder(@NonNull CartListAdapator.ViewHolder holder, int position) {
    holder.titleTxt.setText(foodDomains.get(position).getTitle());
    holder.feeEachItem.setText(String.valueOf(foodDomains.get(position).getFee()));

    holder.plusItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            managementCart.plusNumberFood(foodDomains, holder.getAdapterPosition(), new ChangeNumberItemListener() {
                @Override
                public void changed() {
                    notifyDataSetChanged();
                    changeNumberItemListener.changed();
                }
            });
        }
    });

相关问题