【问题标题】:getAdapterPosition() is deprecated不推荐使用 getAdapterPosition()
【发布时间】:2020-07-24 07:06:20
【问题描述】:

我已将我的 targetSdkVersion 从 28 更新到 30,我注意到 getAdapterPosition() 已被弃用(我不确定这是什么时候发生的)。

documentation 中,他们说:

此方法已弃用。
当适配器嵌套其他适配器时,此方法会令人困惑。如果你在适配器的上下文中调用它,你可能想调用getBindingAdapterPosition(),或者如果你想要 RecyclerView 看到的位置,你应该调用getAbsoluteAdapterPosition()

文档还说:

注意,如果你查询 RecyclerView 看到的位置,你应该使用getAbsoluteAdapterPosition()(例如你想用它来保存滚动状态)。如果你是查询位置来访问 RecyclerView.Adapter 的内容,你应该使用getBindingAdapterPosition()

我的理解是:

  • getBindingAdapterPosition 应该在您想要获取适配器位置时使用(如果它仍然存在于适配器中)。如果适配器中不再存在,则返回-1(NO_POSITION)。
  • getAbsoluteAdapterPosition 应该用于获取RecyclerView 看到的位置。例如,如果某个项目已被删除,但尚未从ViewHolder 中删除。

换句话说,如果我的Adapter 中有4 项目,我删除位置0 并在项目从ViewHolder 中删除之前查询getAbsoluteAdapterPositiongetBindingAdapterPosition,然后@987654340 @ 将返回0(因为视图仍在ViewHolder 中)和getBindingAdapterPosition 返回-1(因为它不再存在于适配器中)。


我通过记录以下内容测试了差异:

Log.e("difference", "getAdapterPosition = "+myHolder.getAdapterPosition()+" getBindingAdapterPosition = "+myHolder.getBindingAdapterPosition()+" getAbsoluteAdapterPosition = "+myHolder.getAbsoluteAdapterPosition());

它们返回完全相同的值。我看不出有什么区别。

我也发现在调用notifyItemChangednotifyDataSetChangednotifyItemRangeChanged 之前或之后没有区别。但是当我删除位置0 并调用notifyItemRemoved 时,它会返回-1(对于所有这些)。

我的问题

我是否正确理解了这一点,我们应该什么时候使用哪个?还有,什么时候会有区别?

【问题讨论】:

  • 如果使用1.2.0中引入的新的ConcatAdapter会有所不同。在这种情况下,getBindingAdapterPosition() 返回特定适配器中的位置,而不是整个ConcatAdapter。相反,getAbsoluteAdapterPosition() 返回ConcatAdapter 中的位置。
  • @GabrieleMariotti 嗯,这很有道理。那么这是否意味着,如果我只有一个适配器,那么我可以使用getBindingAdapterPosition()getAbsoluteAdapterPosition(),还是会有区别?
  • 另外,如果您检查源代码,getAdapterPosition() 现在会返回 getBindingAdapterPosition();
  • @GabrieleMariotti 如果您有时间,请为我提供除此之外的答案。我查看了源代码,正如您所提到的,getAdapterPosition(); 被替换为getBindingAdapterPosition();。我认为可以肯定地说,当我们使用单个适配器时,我们应该使用 getBindingAdapterPosition();
  • 我个人认为这种弃用是不必要的。在 98% 的情况下,ConcatAdapter 甚至不会被使用,但 ViewHolder 最常用的方法之一已被重命名以说明其存在。

标签: android android-recyclerview android-adapter


【解决方案1】:

recyclerview:1.2.0-alpha02 引入了 MergeAdapter 已重命名为 ConcatAdapterrecyclerview:1.2.0-alpha04
这个 RecyclerView Adapter 可以线性组合多个适配器

类似:

FirstAdapter adapter1 = ...;
SecondAdapter adapter2 = ...;
ConcatAdapter merged = new ConcatAdapter(adapter1, adapter2);
recyclerView.setAdapter(mergedAdapter);

作为此更改的一部分,方法 getAdapterPosition() 已被弃用,因为当适配器嵌套其他适配器时该名称令人困惑。现在您应该使用方法getBindingAdapterPosition() 返回特定适配器 (bindingAdapter) 中的位置。

同时查看RecyclerView.ViewHolder的源码:

    @Deprecated
    public final int getAdapterPosition() {
        return getBindingAdapterPosition();
    }

相反,getAbsoluteAdapterPosition() 方法返回项目相对于整个 RecyclerView 的适配器位置。如果您使用的是 ConcatAdapter,则它是 ConcatAdapter 中的位置,而不是单个 bindingAdapter 中的位置。

只是一个带有 2 个适配器的示例:

更多详情请见official blog post

【讨论】:

  • 这是否意味着绑定适配器位置是我们从模型列表中获取正确数据所需的,因为调用 getAdapterPosition 现在只在内部使用 getBindingAdapterPosition?
  • @MihaeKheel 是的
  • 如果只有一个适配器,那么所有出现的getAdapterPosition都应该改为getBindingAdapterPosition。对吗?
  • @SouravKannanthaB 是的
  • 如果不使用 ConcatAdapter,也可以使用 getAbsoluteAdapterPosition。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
  • 2012-11-14
  • 2019-11-08
  • 2019-11-08
  • 2020-01-03
  • 2011-12-02
  • 2015-01-24
相关资源
最近更新 更多