onBindViewHolder中position报错:请勿视为固定值的解决方案求助
解决RecyclerView Adapter中"Do not treat position as fixed; only use immediately and call myViewHolder.getAdapterPosition() to look it up later"报错
问题根源
你在onBindViewHolder的点击事件回调里直接使用了方法参数的position,这个值仅在onBindViewHolder执行时有效。当RecyclerView的Adapter数据发生更新(比如增删条目),ViewHolder被复用时,原来的position会和当前显示的条目位置不匹配,系统因此抛出警告。
解决办法
直接在点击事件里调用myViewHolder.getAdapterPosition()获取当前条目的实时位置,同时增加位置有效性判断,避免崩溃:
修改后的完整代码:
public void onBindViewHolder(MyViewHolder myViewHolder, int position) { JPGCreationActivity.this.pos = position; myViewHolder.imgPhoto.setImageBitmap(BitmapFactory.decodeFile(this.data.get(position))); myViewHolder.tvImageName.setText(new File(this.data.get(position)).getName()); myViewHolder.itemView.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { int currentPosition = myViewHolder.getAdapterPosition(); // 位置无效时直接返回,防止数据错位或崩溃 if (currentPosition == RecyclerView.NO_POSITION) { return; } Intent intent = new Intent(MyAlbumAdapter.this.mContext, FullScreenViewActivity.class); intent.putExtra("ImagePosition", currentPosition); intent.putStringArrayListExtra("arraylist", MyAlbumAdapter.this.data); MyAlbumAdapter.this.mContext.startActivity(intent); } }); }
额外提醒
- 不要把
position参数赋值给全局变量(比如你代码里的JPGCreationActivity.this.pos = position;),全局变量存储的旧位置在数据更新后会失效,同样可能引发问题。如果需要全局使用位置,建议在需要时通过getAdapterPosition()实时获取。 - 网上部分旧代码可能没考虑数据更新后的ViewHolder复用问题,所以写法和你一致,但这种写法存在潜在bug,建议优先使用
getAdapterPosition()的方式。
内容的提问来源于stack exchange,提问作者Phong Dương Hùng
相关产品推荐
相关产品推荐

