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

RecyclerView报Do not treat position as fixed 用getAdapterPosition仍点击崩溃怎么解决

Android RecyclerView适配器点击崩溃问题解决方案

崩溃原因

  • holder.getAdapterPosition() 在ViewHolder已被回收、对应条目已被移除但列表未完成刷新的场景下,会返回常量 RecyclerView.NO_POSITION(值为-1)
  • 直接将无效位置传给PlayerActivity后,后续从音乐列表取值时会触发数组下标越界异常,导致崩溃

修复方案

1. 核心修复:增加位置有效性判断

点击事件触发后先校验获取到的位置是否合法,仅合法位置才执行后续跳转逻辑

2. 性能优化:迁移点击事件位置

将点击事件从onBindViewHolder移到ViewHolder构造方法中,避免每次条目复用时重复创建点击事件实例,减少不必要的内存开销

完整修改后代码

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(R.drawable.ic_launcher_background).into(holder.album_art);
    }
}

@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);
        
        // 点击事件移到此处
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int adapterPosition = getAdapterPosition();
                // 增加有效性判断,过滤无效位置
                if (adapterPosition != RecyclerView.NO_POSITION) {
                    Intent intent = new Intent(mcontext, PlayerActivity.class);
                    intent.putExtra("position", adapterPosition);
                    mcontext.startActivity(intent);
                }
            }
        });
    }
}

private byte[] getAlbumArt(String uri) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    retriever.setDataSource(uri);
    byte[] art = retriever.getEmbeddedPicture();
    retriever.release();
    return art;
}

额外注意事项

  • 如果列表存在增删改操作,优先使用notifyItemInserted、notifyItemRemoved、notifyItemChanged等定向刷新方法,不要全量调用notifyDataSetChanged,可保证getAdapterPosition返回值的准确性
  • 不要在onBindViewHolder之外的场景使用onBindViewHolder传入的position参数,所有延迟调用场景(比如点击、异步回调)统一使用getAdapterPosition获取实时位置

内容的提问来源于stack exchange,提问作者sathish kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:48:00