• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

RecyclerViewgetLayoutPosition 和 getAdapterPosition

武飞扬头像
BugFree张瑞
帮助1

一、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 和用户在屏幕上看到的一定是一样的。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgiifje
系列文章
更多 icon
同类精品
更多 icon
继续加载