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 。 . .
自新支持库版本 (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 。 . .