RecyclerView固定position使用报错,调用getAdapterPosition仍未解决
解决FirebaseRecyclerAdapter中"Do not treat position as fixed"警告问题
问题根源
你遇到的警告核心原因是:在按钮点击的回调方法中直接使用了onBindViewHolder传入的position参数。这个position是ViewHolder绑定瞬间的临时位置值,当列表数据发生更新(比如新增、删除、排序)后,旧的position会失效,即使换成holder.getAdapterPosition(),如果直接在getRef()中使用,也可能因为列表状态变化导致位置无效。
两种可行解决方法
方法一:绑定阶段存储Item的Key到ViewHolder
这种方式最安全,直接把当前Item的Firebase Key存储在ViewHolder中,点击时直接取用:
- 修改
AdminSiparisViewHolder,添加存储Key的字段:
public static class AdminSiparisViewHolder extends RecyclerView.ViewHolder{ public TextView kullanıcıİsmi,kullanıcıTelefon,kullanıcıToplamTutar,kullanıcıTarih,kullanıcıGonderiAddress; public Button siparisGosterBtn; public String itemKey; // 新增字段存储当前Item的Key public AdminSiparisViewHolder(@NonNull View itemView) { super(itemView); // 原有的findViewById代码不变 kullanıcıİsmi=itemView.findViewById(R.id.siparis_kullanıcı_adı); kullanıcıTelefon=itemView.findViewById(R.id.siparis_telefon_numarası); kullanıcıToplamTutar=itemView.findViewById(R.id.siparis_toplam_fiyat); kullanıcıGonderiAddress=itemView.findViewById(R.id.siparis_address_il); kullanıcıTarih=itemView.findViewById(R.id.siparis_tarih_saat); siparisGosterBtn=itemView.findViewById(R.id.siparis_kontrol_btn); } }
- 在
onBindViewHolder中给ViewHolder的itemKey赋值:
@Override protected void onBindViewHolder(@NonNull AdminSiparisViewHolder holder,int position, @NonNull AdminSiparis model) { // 原有的文本赋值代码不变 holder.kullanıcıİsmi.setText("İsim:"+model.getIsim()); holder.kullanıcıTelefon.setText("Telefon:"+model.getTelefon()); holder.kullanıcıToplamTutar.setText("Toplam Miktar:"+model.getToplamMiktar()+"TL"); holder.kullanıcıTarih.setText("Siparis Tarih:"+model.getTarih()+""+model.getZaman()); holder.kullanıcıGonderiAddress.setText("Address:"+model.getAddress()+","+model.getIl()); // 存储当前Item的Firebase Key到ViewHolder holder.itemKey = getRef(position).getKey(); holder.siparisGosterBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 直接使用ViewHolder中存储的Key String kID=holder.itemKey; Intent intent=new Intent(AdminYeniSiparisActivity.this,AdminKullaniciUrunActivity.class); intent.putExtra("kid",kID); startActivity(intent); } }); }
方法二:点击时获取当前有效位置再取引用
如果不想修改ViewHolder,可以在点击事件中先获取当前有效的适配器位置,再获取引用,注意要判断位置有效性:
holder.siparisGosterBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int currentPosition = holder.getAdapterPosition(); // 先判断位置是否有效(避免列表更新后位置失效的情况) if(currentPosition != RecyclerView.NO_POSITION){ String kID=getRef(currentPosition).getKey(); Intent intent=new Intent(AdminYeniSiparisActivity.this,AdminKullaniciUrunActivity.class); intent.putExtra("kid",kID); startActivity(intent); } } });
为什么之前的尝试无效?
你之前尝试调用holder.getAdapterPosition()但没解决问题,大概率是因为你仍然在点击事件中使用了原来的position参数,或者没有对获取到的位置做有效性判断。上面两种方法都避免了依赖绑定瞬间的旧position,而是使用当前状态下的有效位置或预存的Key。
内容的提问来源于stack exchange,提问作者Beritan Koç
相关产品推荐
相关产品推荐

