RecyclerAdapter写入Firebase时出现supplierClass空指针异常
问题根因
你遇到的空指针问题由3个核心错误导致:
- 空对象引用:你在
MyViewHolder构造方法中new supplierClass sc创建的是一个完全没有赋值的空对象,和onBindViewHolder中绑定列表数据的sc局部变量没有任何关联,点击按钮时调用空对象的getsName()方法必然触发空指针。 - 点击事件绑定位置错误:
RecyclerView.ViewHolder会被多个列表项复用,在构造方法里绑定点击事件时,无法获取当前列表项对应的真实绑定数据和位置。 - 冗余逻辑+潜在空指针:你写入数据前额外添加了
addValueEventListener读取节点完全没有必要,不仅多余,还会导致后续节点数据变化时重复触发写入逻辑;同时FirebaseAuth.getInstance().getCurrentUser()在用户未登录时会返回null,直接调用getUid()也存在空指针风险。
修正代码
把点击事件移到onBindViewHolder中,直接使用当前位置绑定的实体对象操作,去掉多余逻辑,修正后代码如下:
public class recyclerAdapter extends RecyclerView.Adapter<recyclerAdapter.MyViewHolder> { Context context; ArrayList<supplierClass> list; public recyclerAdapter(Context context, ArrayList<supplierClass> list) { this.context = context; this.list = list; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(context).inflate(R.layout.item,parent,false); return new MyViewHolder(v); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { // 获取当前列表项绑定的真实数据 supplierClass sc = list.get(position); holder.sName.setText(sc.getsName()); holder.materialName.setText(sc.getMaterialName()); holder.CATEGORY.setText(sc.getCATEGORY()); // 在这里绑定点击事件,直接使用当前位置的sc对象 holder.btnSelect.setOnClickListener(v -> { FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); // 加非空判断避免未登录崩溃 if (user == null) return; String id = user.getUid(); DatabaseReference ref = FirebaseDatabase.getInstance().getReference("dashboard"); // 直接写入对应供应商名称,不需要先读节点 ref.child(id).setValue(sc.getsName()); }); } @Override public int getItemCount() { return list.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder{ TextView sName,materialName,CATEGORY; Button btnSelect; public MyViewHolder(@NonNull View itemView) { super(itemView); sName = itemView.findViewById(R.id.lblSupplierName); materialName = itemView.findViewById(R.id.lblMaterial); CATEGORY = itemView.findViewById(R.id.lblLocation); btnSelect = itemView.findViewById(R.id.btnSelect); } } }
额外优化建议
- 类名建议遵循Java大驼峰命名规范,比如
RecyclerAdapter、SupplierClass,避免和普通变量混淆 - 如果列表数据后续会刷新,建议在
onBindViewHolder中给控件绑定事件前先清空旧的监听,避免ViewHolder复用导致的点击事件错乱
内容的提问来源于stack exchange,提问作者yanish appadoo
相关产品推荐
相关产品推荐

