RecyclerView onBindViewHolder的position不准问题
一、onBindViewHolder的触发时机
当adapter中添加一个数据的时候,notifyItemInserted(index)会触发一次onBindViewHolder,此时position就是index,而index之后的数据并不会触发onBindViewHolder
二、position和holder.getAdapterPosition
当notifyItemInserted(index)触发onBindViewHolder的时候,传入的position就是index,但如果此时使用position设置一些监听器的时候,当后续再次添加item,监听器中的position就可能出现错误,此时应该使用holder.getAdapterPosition,这个可以保证用户在点击某一项的时候,获取到点击的真正的position
三、holder.getLayoutPosition和holder.getAdapterPosition
getLayoutPosition是当前界面已经看见的位置,可能存在刚调用notifyItemInserted还没有来得及重新绘制显示,距离getAdapterPosition时间 < 16ms
四、引用参考
In order to argue the difference(s) of getAdapterPosition(), getLayoutPosition(), and also position; we would notice the cases below:
1.position argument in onBindViewHolder() method:
We can use the position to bind data to the view and it is okay to use position argument to do this, but it is not okay to use position argument to handle user clicks and if you used it you will see a warning tells you “not to treat position as fixed and use holder.getAdapterPosition() instead”.
2.getAdapterPosition():
This method always consists the updated adapter’s position of the holder. It means whenever you clicked on an item, you ask the adapter about it’s position. so you will get the latest position of this item in terms of Adapter’s logic.
3.getLayoutPosition():
Sometimes, it is needed to find the position in terms of the updated layout (the last passed layout that the user is seeing now), for example: If the user asks for the third position he can see and you use swipe/dismiss for items or apply any animation or decorations for items it will be better to use getLayoutPosition() instead of getAdapterPosition(), cause you will always be sure that you are dealing with the items’ position in terms of the latest passed layout.
https://stackoverflow.com/questions/29684154/recyclerview-viewholder-getlayoutposition-vs-getadapterposition