RecyclerView仅显示Firebase实时数据库单一条目问题排查
问题根源分析
- Query指向错误:当前
FirebaseRecyclerOptions的查询对象是根节点Ingredient,而非当前用户专属的食材节点fridgeRef.child(currentUserID),导致适配器获取的是所有用户数据,而非目标用户的食材列表。 - onBindViewHolder逻辑混乱:
- 在视图绑定阶段嵌套添加
ValueEventListener,会重复发起数据库请求,引发多次无意义的视图刷新。 - 硬编码判断
Garlic和Onion,并在循环中直接覆盖同一个ViewHolder的文本内容,最终只会显示最后一个匹配的食材(Onion),无法动态遍历所有子节点。
- 在视图绑定阶段嵌套添加
- 未利用适配器的模型映射能力:没有通过
model参数直接获取数据,而是手动查询数据库,违背了FirebaseRecyclerAdapter的设计逻辑。
修正方案
1. 确保fridgeItem模型类匹配数据结构
创建对应食材节点的模型类,包含Expiry和Ingredient字段:
public class fridgeItem { private String Expiry; private int Ingredient; // Firebase必须的空构造函数 public fridgeItem() {} public fridgeItem(String expiry, int ingredient) { Expiry = expiry; Ingredient = ingredient; } // Getter和Setter方法 public String getExpiry() { return Expiry; } public void setExpiry(String expiry) { Expiry = expiry; } public int getIngredient() { return Ingredient; } public void setIngredient(int ingredient) { Ingredient = ingredient; } }
2. 修正查询指向目标节点
将FirebaseRecyclerOptions的查询对象改为当前用户的食材节点:
FirebaseRecyclerOptions<fridgeItem> options = new FirebaseRecyclerOptions.Builder<fridgeItem>() .setQuery(fridgeRef.child(currentUserID), fridgeItem.class) .build();
3. 重写onBindViewHolder逻辑
移除嵌套的数据库监听,通过model获取食材数据,利用getRef(position).getKey()获取食材名称:
@Override protected void onBindViewHolder(@NonNull fridgeViewHolder holder, int position, @NonNull fridgeItem model) { // 获取食材节点的Key(如Garlic/Onion) String itemName = getRef(position).getKey(); String itemExpiry = model.getExpiry(); holder.ingredName.setText(itemName); holder.ingredExpiry.setText(itemExpiry); }
4. 完整修正后的onStart方法
@Override public void onStart() { super.onStart(); FirebaseRecyclerOptions<fridgeItem> options = new FirebaseRecyclerOptions.Builder<fridgeItem>() .setQuery(fridgeRef.child(currentUserID), fridgeItem.class) .build(); FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder> adapter = new FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder>(options) { @Override protected void onBindViewHolder(@NonNull fridgeViewHolder holder, int position, @NonNull fridgeItem model) { String itemName = getRef(position).getKey(); String itemExpiry = model.getExpiry(); holder.ingredName.setText(itemName); holder.ingredExpiry.setText(itemExpiry); } @NonNull @Override public fridgeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ingredientrecycle, parent, false); return new fridgeViewHolder(view); } }; myIngredientList.setAdapter(adapter); adapter.startListening(); }
5. 额外优化:移除ScrollView嵌套
RecyclerView自带滚动功能,嵌套ScrollView会导致滚动冲突和性能问题,修改fragment_fridge.xml:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".fridge"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/fridge" android:textSize="22sp" android:layout_marginStart="32dp" android:layout_marginEnd="32dp" android:layout_marginTop="32dp" android:textStyle="bold" android:textColor="#FF5D36" android:fontFamily="@font/roboto"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/fridgetext" android:textSize="20sp" android:layout_marginStart="32dp" android:layout_marginEnd="32dp" android:fontFamily="@font/roboto"/> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="32dp" android:paddingEnd="32dp" android:paddingTop="32dp"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/ingredientList" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> </LinearLayout> </FrameLayout>
内容的提问来源于stack exchange,提问作者trophē
相关产品推荐
相关产品推荐

