0

I have this error in my code:

Do not treat position as fixed; only use immediately and call holder.getAdapterPosition() to look it up later.

I even used holder.getAdapterPosition() in the position place, but it still keeps crashing the app when I click the items.

MusicAdapter(Context mcontext, ArrayList<MusicFile> mfiles) {
    this.mfiles = mfiles;
    this.mcontext = mcontext;
}

@Override // androidx.recyclerview.widget.RecyclerView.Adapter
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new MyViewHolder(LayoutInflater.from(this.mcontext).inflate(R.layout.music_items, parent, false));
}

public void onBindViewHolder( final MyViewHolder holder,  int position) {
    holder.file_name.setText(this.mfiles.get(position).getTitle());
    byte[] image = getAlbumArt(this.mfiles.get(position).getPath());
    if (image != null) {
        Glide.with(this.mcontext).asBitmap().load(image).into(holder.album_art);
    } else {
        Glide.with(this.mcontext).load((int) R.drawable.ic_launcher_background).into(holder.album_art);
    }



    holder.itemView.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            Intent intent = new Intent(MusicAdapter.this.mcontext, PlayerActivity.class);
            intent.putExtra("position", holder.getAdapterPosition());
            MusicAdapter.this.mcontext.startActivity(intent);
        }
    });
}

@Override // androidx.recyclerview.widget.RecyclerView.Adapter
public int getItemCount() {
    return this.mfiles.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder {
    ImageView album_art;
    TextView file_name;
    LinearLayout linearLayout;

    public MyViewHolder(View itemView) {
        super(itemView);
        this.file_name = (TextView) itemView.findViewById(R.id.music_file_name);
        this.album_art = (ImageView) itemView.findViewById(R.id.music_img);
        linearLayout = itemView.findViewById(R.id.linear_layout);
    }
}

private byte[] getAlbumArt(String uri) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    retriever.setDataSource(uri);
    byte[] art = retriever.getEmbeddedPicture();
    retriever.release();
    return art;
    }
}
BSMP
  • 4,596
  • 8
  • 33
  • 44
  • Does this answer your question? [Lint error "Do not treat position as fixed; only use immediately..."](https://stackoverflow.com/questions/34942840/lint-error-do-not-treat-position-as-fixed-only-use-immediately) – BSMP Sep 11 '21 at 17:29

1 Answers1

1

Imagine that we have a RecyclerView that will display 10 items so it will create 10 items and call onBindView for those 10 items and pass the positions from 0 to 9, so if you fixed the position by using it to handle user clicks and later you added an item at position 0 and notified the data set that you inserted a new item by notifyItemInserted() the RecyclerView will create a new item with position 0 and pass it to the layout but the pre created ones still have the old positions and if you logged those positions you will have 00123…9 which is not true it should be 0123…10. Here come the power of holder.getAdapterPosition().

@Override
public void onBindViewHolder(@NonNull GalleryViewAdapter holder,final int position) {

    Glide.with(context).load(images.get(position)).into(holder.imageView);

    holder.imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(context, FullImageview.class);
            intent.putExtra("image", images.get(holder.getAdapterPosition()));
            context.startActivity(intent);

        }
    });

}

now its fine to use holder.getAdapterPosition for user click event notice that i used getAdapterPosition to bind data and used getLayoutPosition to tell the user the position of the pressed item.