RecyclerView.ViewHolder – getLayoutPosition vs getAdapterPosition

由于新的支持库版本(22.x)RecyclerView.ViewHolder类的getPosition()方法已被弃用,而不是主题中提到的方法。 我没有真正从阅读文档中获得改变。 请问有人能解释一下外行的差别吗?

我有以下用例 – 我给我的适配器一个列表,也希望能够关联每个列表项的额外信息。 我有一个位置到额外的映射,这个映射对于持有者是可用的,这样他们可以为他们的位置获取额外的东西,并用它做东西。 在持有人中,我应该使用哪种方法?

索引0和1处的列表项在切换位置时,​​持有者位置会发生什么情况? 这些方法返回什么?

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

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

在您的用例中,由于您的数据与您的适配器内容相关(并且我认为数据在适配器更改的同时发生了更改),因此您应该使用adapterPosition

要小心,如果你调用notifyDataSetChanged() ,因为它使一切无效,RecyclerView不知道ViewHolder的适配器位置,直到计算下一个布局。 在这种情况下, getAdapterPosition()将返回RecyclerView#NO_POSITION-1 )。

但是让我们说如果你调用了notifyItemInserted(0) ,先前在位置0的ViewHolder的getAdapterPosition()将立即开始返回1 。 所以只要你调度细粒度的通知事件,你总是处于良好的状态(即使新的布局尚未计算,我们知道适配器的位置)。

另一个例子,如果你正在做一些用户点击,如果getAdapterPosition()返回NO_POSITION ,最好忽略点击,因为你不知道用户点击(除非你有其他机制,例如稳定的id来查找项目)。

当布局位置良好时编辑

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

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

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