RecyclerView.ViewHolder - getLayoutPosition 与 getAdapterPosition

RecyclerView.ViewHolder - getLayoutPosition vs getAdapterPosition

自新支持库版本 (22.x) 以来,RecyclerView.ViewHolder class 的 getPosition() 方法已被弃用,以代替主题中提到的方法。我真的没有从阅读文档中得到什么区别。 有人可以通俗地解释一下区别吗?

我有以下用例 - 我给我的适配器一个 List,并且还希望能够为每个列表项关联额外信息。我有一个位置到额外的映射,并且该映射可供持有者使用,以便他们可以为他们的位置获取额外的并用它来做事。在holder中,我应该使用哪种方法?

当索引 0 和 1 的列表项交换位置时,​​holder 的位置会发生什么变化?方法是什么 return?

这是一个棘手的情况,抱歉文档不够。

当适配器内容改变时(并且您调用 notify***())RecyclerView 请求新的布局。从那一刻起,直到布局系统决定计算新布局(<16 毫秒),布局位置和适配器位置可能不匹配,因为布局尚未反映适配器更改。

在您的用例中,由于您的数据与您的适配器内容相关(并且我假设数据与适配器更改同时更改),您应该使用 adapterPosition.

但是要小心,如果您正在调用 notifyDataSetChanged(),因为它会使所有内容无效,RecyclerView 在计算下一个布局之前不知道 ViewHolder 的适配器位置。在这种情况下,getAdapterPosition() 将 return RecyclerView#NO_POSITION (-1).

但是假设您调用了 notifyItemInserted(0),之前位于 0 位置的 ViewHolder 的 getAdapterPosition() 将开始 returning 1立即地。因此,只要您分派细粒度通知事件,您就始终处于良好状态(即使尚未计算新布局,我们也知道适配器位置)。

再比如,如果你在用户点击上做某事,如果getAdapterPosition() returns NO_POSITION,最好忽略那个点击,因为你不知道用户是什么单击(除非您有其他机制,例如用于查找项目的稳定 ID)。

当布局位置合适时编辑

假设您正在使用 LinearLayoutManager 并且想要访问当前单击项目上方的 ViewHolder。在这种情况下,您应该使用布局位置来获取上面的项目。

mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)

您必须使用布局位置,因为它与用户当前在屏幕上看到的相匹配。

为了论证getAdapterPosition()getLayoutPosition()position的区别;我们会注意到以下情况:

1.position onBindViewHolder() 方法中的参数:

我们可以使用 position 将数据绑定到视图,使用 position 参数可以做到这一点,但是使用 position 参数是不行的处理用户点击,如果你使用它,你会看到一条警告,告诉你“不要将 position 视为固定的,而是使用 holder.getAdapterPosition()”。

2.getAdapterPosition():

此方法始终包含 holder 的更新适配器位置。这意味着无论何时单击某个项目,您都会向适配器询问它的 position。这样你就可以根据Adapter的逻辑得到这个item的最新位置。

3.getLayoutPosition():

有时,需要根据更新的布局(用户现在看到的最后一个通过的布局)找到position,例如:如果用户要求第三个position 他可以看到并且你对物品使用 swipe/dismiss 或为物品应用任何动画或装饰 使用 getLayoutPosition() 而不是 getAdapterPosition() 会更好,因为你将始终确保您根据最新通过的布局处理项目的位置。


有关这方面的更多信息;见 here 。 . .