RecyclerView:getLayoutPosition 和 getAdapterPosition

一、getPosition

/**
 * @deprecated This method is deprecated because its meaning is ambiguous due to the async
 * handling of adapter updates. Please use {@link #getLayoutPosition()} or
 * {@link #getAdapterPosition()} depending on your use case.
 *
 * @see #getLayoutPosition()
 * @see #getAdapterPosition()
 */
@Deprecated
public final int getPosition() {
    return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
}

二、getLayoutPosition

/**
 * Returns the position of the ViewHolder in terms of the latest layout pass.
 * <p>
 * This position is mostly used by RecyclerView components to be consistent while
 * RecyclerView lazily processes adapter updates.
 * <p>
 * For performance and animation reasons, RecyclerView batches all adapter updates until the
 * next layout pass. This may cause mismatches between the Adapter position of the item and
 * the position it had in the latest layout calculations.
 * <p>
 * LayoutManagers should always call this method while doing calculations based on item
 * positions. All methods in {@link RecyclerView.LayoutManager}, {@link RecyclerView.State},
 * {@link RecyclerView.Recycler} that receive a position expect it to be the layout position
 * of the item.
 * <p>
 * If LayoutManager needs to call an external method that requires the adapter position of
 * the item, it can use {@link #getAdapterPosition()} or
 * {@link RecyclerView.Recycler#convertPreLayoutPositionToPostLayout(int)}.
 *
 * @return Returns the adapter position of the ViewHolder in the latest layout pass.
 * @see #getAdapterPosition()
 */
public final int getLayoutPosition() {
    return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
}

返回布局中最新的计算位置,和用户所见到的位置一致,当做用户输入(例如点击事件)的时候考虑使用

三、getAdapterPosition

/**
 * Returns the Adapter position of the item represented by this ViewHolder.
 * <p>
 * Note that this might be different than the {@link #getLayoutPosition()} if there are
 * pending adapter updates but a new layout pass has not happened yet.
 * <p>
 * RecyclerView does not handle any adapter updates until the next layout traversal. This
 * may create temporary inconsistencies between what user sees on the screen and what
 * adapter contents have. This inconsistency is not important since it will be less than
 * 16ms but it might be a problem if you want to use ViewHolder position to access the
 * adapter. Sometimes, you may need to get the exact adapter position to do
 * some actions in response to user events. In that case, you should use this method which
 * will calculate the Adapter position of the ViewHolder.
 * <p>
 * Note that if you've called {@link RecyclerView.Adapter#notifyDataSetChanged()}, until the
 * next layout pass, the return value of this method will be {@link #NO_POSITION}.
 *
 * @return The adapter position of the item if it still exists in the adapter.
 * {@link RecyclerView#NO_POSITION} if item has been removed from the adapter,
 * {@link RecyclerView.Adapter#notifyDataSetChanged()} has been called after the last
 * layout pass or the ViewHolder has already been recycled.
 */
public final int getAdapterPosition() {
    if (mOwnerRecyclerView == null) {
        return NO_POSITION;
    }
    return mOwnerRecyclerView.getAdapterPositionFor(this);
}

返回数据在 Adapter 中的位置 (也许位置的变化还未来得及刷新到布局中),当使用 Adapter 的时候(例如调用 Adapter 的 notify 的刷新相关方法时)考虑使用。

总结:

  • getLayoutPosition 和 getAdapterPosition 通常情况下是一样的,只有当 Adapter 里面的内容改变了,而 Layout 还没来得及绘制的这段时间之内才有可能不一样,这个时间小于16ms
  • 如果调用的是 notifyDataSetChanged(),因为要重新绘制所有 Item,所以在绘制完成之前 RecyclerView 是不知道 adapterPosition 的,这时会返回-1(NO_POSITION)
  • 但如果用的是 notifyItemInserted(0),那立即就能获取到正确的 adapterPosition,即使新的 Layout 还没绘制完成,比如之前是0的现在就会变成1,因为插入了0, 相当于 RecyclerView 提前帮你计算的,此时getLayoutPosition 还只能获取到旧的值。
  • 总的来说,大多数情况下用 getAdapterPosition,只要不用 notifyDataSetChanged() 来刷新数据就总能立即获取到正确 position 值。

什么情况下用 getLayoutPosition 呢?

就是调用 findViewHolderForLayoutPosition 获取当前点击的 Item 的 ViewHolder 时,因为此时 layout position 和用户在屏幕上看到的一定是一样的。

——乐于分享,共同进步,欢迎补充
——Any comments greatly appreciated
——诚心欢迎各位交流讨论!QQ:1138517609
——GitHub:https://github.com/selfconzrr

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BugFree_张瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值