Firebase Adapter无法获取布尔值设置Spinner选中状态的问题
Firebase Recycler Options布尔值映射失败及Spinner状态不匹配问题修复
一、核心问题分析
1. Model类与数据库键名不匹配
Firebase的POJO映射依赖字段名与数据库键名完全一致,同时getter/setter需符合JavaBean规范:
- 数据库布尔键为
isApproved、isPending、isRejected,但Model类字段是approved、pending、rejected,无法自动映射。 - Model的getter方法命名错误:
Approved()、Pending()、Rejected()不符合规范,应该是isApproved()/getApproved()形式。 - 数据库中存在大小写不一致的字段(如
DATE/date、TIME/time、UID/uid),导致部分字符串字段也可能映射失败。
2. Spinner未初始化选中状态
当前代码仅在用户选择Spinner项时更新数据库,但未在初始化时根据Modal中的布尔值设置Spinner的默认选中项。
二、修复步骤
1. 修正BookingModal类
调整字段名匹配数据库键,同时修正getter/setter命名:
public class BookingModal { private String DATE; private String TIME; private String UID; private boolean isApproved; private boolean isPending; private boolean isRejected; // 空构造函数必须保留,Firebase序列化需要 public BookingModal(){} // 带参构造函数 public BookingModal(String DATE, String TIME, String UID, boolean isApproved, boolean isPending, boolean isRejected) { this.DATE = DATE; this.TIME = TIME; this.UID = UID; this.isApproved = isApproved; this.isPending = isPending; this.isRejected = isRejected; } // 字符串字段的getter/setter public String getDATE() { return DATE; } public void setDATE(String DATE) { this.DATE = DATE; } public String getTIME() { return TIME; } public void setTIME(String TIME) { this.TIME = TIME; } public String getUID() { return UID; } public void setUID(String UID) { this.UID = UID; } // 布尔字段的getter/setter(符合JavaBean规范) public boolean isApproved() { return isApproved; } public void setApproved(boolean isApproved) { this.isApproved = isApproved; } public boolean isPending() { return isPending; } public void setPending(boolean isPending) { this.isPending = isPending; } public boolean isRejected() { return isRejected; } public void setRejected(boolean isRejected) { this.isRejected = isRejected; } }
若数据库中存在小写的
date/time/uid,建议统一改为大写的DATE/TIME/UID;若无法修改数据库,可在Model字段上添加@PropertyName("date")注解强制映射,避免大小写不一致导致的问题。
2. 修正Adapter的onBindViewHolder方法
更新布尔值调用方式,同时在初始化Spinner时设置选中状态:
@Override protected void onBindViewHolder(@NonNull BookingVH holder, int position, @NonNull BookingModal model) { holder.date.setText(model.getDATE()); UserModal userModalDetail = findbyProperty(userModalList, model.getUID()); if (userModalDetail != null) { holder.name.setText(userModalDetail.getName()); holder.matric.setText(userModalDetail.getMatricnumber()); // 初始化Spinner选中状态 initSpinnerSelection(holder.status, model); // 设置Spinner选择监听 setupSpinnerListener(holder.status, userModalDetail.getUID(), model); } Log.d("booleanvalue", model.isPending() + " - " + model.isApproved() + " - " + model.isRejected()); } // 初始化Spinner选中状态 private void initSpinnerSelection(Spinner spinner, BookingModal model) { if (model.isPending()) { spinner.setSelection(0); } else if (model.isApproved()) { spinner.setSelection(1); } else if (model.isRejected()) { spinner.setSelection(2); } } // 设置Spinner选择监听 private void setupSpinnerListener(Spinner v, String uid, BookingModal modal) { v.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { if (i == 0){ mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isPending").setValue(true); mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isApproved").setValue(false); mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isRejected").setValue(false); } else if (i == 1){ mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isApproved").setValue(true); mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isPending").setValue(false); mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isRejected").setValue(false); } else if (i == 2){ mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isRejected").setValue(true); mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isApproved").setValue(false); mDatabase.child("Bookings").child("Kompleks Sukan A").child("Pending").child(uid) .child("isPending").setValue(false); } } @Override public void onNothingSelected(AdapterView<?> adapterView) {} }); }
将Spinner的初始化和监听逻辑拆分,避免重复设置监听,同时确保初始化时根据数据库数据选中对应项。
3. 统一数据库字段大小写
建议将数据库中所有date、time、uid改为DATE、TIME、UID,保持与Model类字段一致。若无法修改数据库,可在Model字段上添加@PropertyName注解:
@PropertyName("date") private String DATE; @PropertyName("time") private String TIME; @PropertyName("uid") private String UID;
同时对应的getter/setter也需添加注解:
@PropertyName("date") public String getDATE() { return DATE; } @PropertyName("date") public void setDATE(String DATE) { this.DATE = DATE; }
三、验证修复效果
- 重新运行App,查看Logcat中的
booleanvalue日志,确认布尔值已正确从数据库获取。 - 进入Activity后,Spinner会自动根据数据库中的布尔值选中对应状态。
- 选择Spinner项时,数据库中的布尔值仍能正确更新。
内容的提问来源于stack exchange,提问作者Mr Learning
相关产品推荐
相关产品推荐

