棉绒错误“不要将位置视为固定位置;只能立即使用……" [英] Lint error "Do not treat position as fixed; only use immediately..."

查看:24
本文介绍了棉绒错误“不要将位置视为固定位置;只能立即使用……"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm contributing to open source library and got lint error "Do not treat position as fixed; only use immediately and call holder.getAdapterPosition() to look it up later" for this code:

  @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() 时,问题就消失了:

I've checked that it is because the position is saved for the future use. It is a question to library creator why they need this logic. But issue disappeared when I change the usage of the position to the usage 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 很满意.为什么?

I assume that conceptually it didn't change much but lint is satisfied now. Why?

推荐答案

RecyclerView.Adapter.onBindViewHolder() 状态:

注意和ListView不同,RecyclerView不会调用这个方法再次,如果项目在数据集中的位置发生变化,除非项目本身无效或无法确定新位置.因此,您应该只使用 position 参数,而获取该方法内部的相关数据项,不应保留它的副本.如果您稍后需要某个项目的位置(例如在单击侦听器),使用 getAdapterPosition() 将更新适配器位置

Note that unlike ListView, RecyclerView will not call this method again if the position of the item changes in the data set unless the item itself is invalidated or the new position cannot be determined. For this reason, you should only use the position parameter while acquiring the related data item inside this method and should not keep a copy of it. If you need the position of an item later on (e.g. in a click listener), use getAdapterPosition() which will have the updated adapter position

因此,从技术上讲,项目可能会重新排列(例如排序或移动)并且不需要绑定,因为项目尚未失效.这意味着如果项目显示相同的数据,则可能不会调用 onBindViewHolder(),而只是它们在列表中的位置/索引发生变化.接收到的 position 变量仅适用于绑定函数的范围,并不总是指向数据集中的正确位置.这就是为什么每次需要更新位置时都必须调用函数 getAdapterPosition().

So, technically items may be re-arranged (like sorted, or moved around) and binding will not be necessary because items are not invalidated yet. This means onBindViewHolder() may NOT be called if items show the same data, but just their position/index in a list changes. The position variable received holds true only for the scope of bind function and will not always point to the correct position in the data set. That's why the function getAdapterPosition() must be called every time updated position is needed.

恕我直言,mLastPosition = holder.getAdapterPosition(); 仍然可能是错误的.因为 item 可能会重新排列并且 mLastPosition 仍然指向旧位置.

IMHO, mLastPosition = holder.getAdapterPosition(); is still potentially wrong. Because item may be re-arranged and mLastPosition still points to old position.

关于为什么 lint 是沉默的,也许 Lint 的规则没有那么彻底.它只是检查 position 参数是否被复制.

About why lint is silent, perhaps Lint's rule is not that thorough. It's only checking whether the position parameter is being copied or not.

这篇关于棉绒错误“不要将位置视为固定位置;只能立即使用……"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆