RecycleView getAdapterPosition() 返回-1

在项目中遇到RecyclerView通过ViewHolder.getAdapterPosition()返回-1的情况。源码显示,当ViewHolder状态为FLAG_REMOVED或者在adapter更新但未进行新布局时会发生这种情况。官方建议在用户事件响应中需要精确的adapter位置时使用此方法。解决办法是在ViewHolder中保存数据源Bean,通过Bean在列表中的位置获取position。问题通常发生在删除或移动item后调用notifyItemMoved()。参考链接提供了更多解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做项目,发现一个问题,RecycleView 通过ViewHolder.getAdapterPosition() 时返回-1,看源码有几种情况会返回NO_POSITION:
1:

public final int getAdapterPosition() {
    if (mOwnerRecyclerView == null) {
        return NO_POSITION;
    }
    return mOwnerRecyclerView.getAdapterPositionFor(this);
}

mOwnerRecyclerView 即为RecyclerView.this本身。
2:

int getAdapterPositionFor(ViewHolder viewHolder) {
    if (viewHolder.hasAnyOfTheFlags( ViewHolder.FLAG_INVALID |
            ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)
            || !viewHolder.isBound()) {
        return RecyclerView.NO_POSITION;
    }
    return mAdapterHelper.applyPendingUpdatesToPosition(viewHolder.mPosition);
}

当ViewHolder处于FLAG_REMOVED 等状态时会返回NO_POSITION。

为什么会有NO_POSITION看一下官方解释:

Returns the Adapter position of the item represented by this ViewHolder.

Note that this might be different than the getLayoutPosition() if there are pending adapter updates but a new layout pass has not happened yet.

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.

Note that if you’ve called notifyDataSetChanged(), until the next layout pass, the return value of this method will be NO_POSITION.

The adapter position of the item if it still exists in the adapter. NO_POSITION if item has been removed from the adapter, notifyDataSetChanged() has been called after the last layout pass or the ViewHolder has already been recycled.

正常情况是不会出现,我的操作是,删除、移动一个item,之后notifyItemMoved() 再次获取getAdapterPosition()就会返回NO_POSITION

我的解决方案是,在ViewHolder中持有数据源Bean。 通过bean在list中的位置来获取position。


参考链接:
http://blog.youkuaiyun.com/newmandirl/article/details/50854733
https://stackoverflow.com/questions/36908448/android-getadapterposition-returns-1-after-deleting-an-item
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#getAdapterPosition%28%29

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值