You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何RecyclerView条目位置返回值为-1?

Fixing RecyclerView LongClick Position = -1 Issue

Hey there! Let's tackle that frustrating problem where you get a -1 position when trying to delete RecyclerView items via long press. This is a common pitfall with RecyclerView's view recycling mechanism, so here are the most reliable fixes and explanations:

1. Use getBindingAdapterPosition() instead of getAdapterPosition()

The old getAdapterPosition() method can return -1 (aka RecyclerView.NO_POSITION) if the ViewHolder has been recycled or the adapter's data has changed since the ViewHolder was bound. Starting with AndroidX RecyclerView 1.2.0, getBindingAdapterPosition() is the safer choice—it accounts for the current bound adapter (critical if you're using something like ConcatAdapter) and gives a more accurate position.

Always add a check to ensure the position is valid before proceeding with deletion:

holder.itemView.setOnLongClickListener(v -> {
    int currentPosition = holder.getBindingAdapterPosition();
    if (currentPosition != RecyclerView.NO_POSITION) {
        // Safe to perform delete operation here
        removeItem(currentPosition);
        return true;
    }
    return false;
});

2. Reset click listeners in onBindViewHolder()

RecyclerView reuses ViewHolders, so if you set a click listener once (like in onCreateViewHolder()), the listener might still reference an old position when the ViewHolder is reused. Always reattach the long click listener inside onBindViewHolder() to ensure it's tied to the current item's position:

@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
    // Bind your data to the ViewHolder first
    holder.bind(mDataList.get(position));

    // Reset the long click listener for the current item
    holder.itemView.setOnLongClickListener(v -> {
        int validPosition = holder.getBindingAdapterPosition();
        if (validPosition != RecyclerView.NO_POSITION) {
            removeItem(validPosition);
            return true;
        }
        return false;
    });
}

3. Update your data set correctly

When deleting an item, make sure you modify your data collection first, then notify the adapter with the specific position change—not just notifyDataSetChanged(). Using notifyItemRemoved() helps RecyclerView maintain correct position tracking for remaining items:

private void removeItem(int position) {
    // Remove the item from your data source first
    mDataList.remove(position);
    // Notify the adapter of the exact item removal
    notifyItemRemoved(position);
    // Optional: Notify subsequent items their positions have shifted (for smooth animations)
    notifyItemRangeChanged(position, mDataList.size() - position);
}

Avoid notifyDataSetChanged() here—it forces a full refresh, which can break position tracking and kill animations.

4. Enable stable IDs

Setting stable IDs helps RecyclerView track items more reliably, even when data changes. Enable this in your adapter constructor and override getItemId() to return a unique ID for each item:

public class MyItemAdapter extends RecyclerView.Adapter<ItemViewHolder> {
    public MyItemAdapter() {
        setHasStableIds(true);
    }

    @Override
    public long getItemId(int position) {
        // Return a unique ID for your item (e.g., from your data model's ID field)
        return mDataList.get(position).getUniqueId();
    }
}

5. Avoid holding references to ViewHolders outside onBindViewHolder()

If you store ViewHolder references elsewhere (like in a list), those references might point to recycled ViewHolders that no longer have a valid position. Stick to handling interactions directly within onBindViewHolder() or ensure any stored references are actively bound to the RecyclerView.

Quick Recap

The biggest fixes are:

  • Replace getAdapterPosition() with getBindingAdapterPosition()
  • Always check if the position is not RecyclerView.NO_POSITION before acting
  • Reset click listeners in onBindViewHolder()
  • Use precise adapter notifications (notifyItemRemoved() instead of notifyDataSetChanged())

These steps should eliminate those random -1 position issues and make your long-press deletion work reliably.

内容的提问来源于stack exchange,提问作者Srinivas Nahak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:25:31