我的JSON是:
{
"Ingredient": {
"hgO9joLhmfh4Wjn7xYpyqcYmNOB3": {
"Garlic": {
"Expiry": "2022-11-12",
"Ingredient": 1
},
"Onion": {
"Expiry": "2022-11-12",
"Ingredient": 1
}
}
}
}
其中hgO9joLhmfh4Wjn7xYpyqcYmNOB3
是当前用户 UID。这里的问题是RecycleView仅显示数据库中的单个项目,在我的情况下是Onion
节点。为什么它没有为fridgeRef.child(currentUserID)
节点下的每个子节点循环?
Java代码
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
ingredientView = inflater.inflate(R.layout.fragment_fridge, container, false);
myIngredientList = (RecyclerView) ingredientView.findViewById(R.id.ingredientList);
myIngredientList.setLayoutManager(new LinearLayoutManager(getContext()));
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
fridgeRef = FirebaseDatabase.getInstance().getReference().child("Ingredient");
return ingredientView;
}
@Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<fridgeItem> options
new FirebaseRecyclerOptions.Builder<fridgeItem>()
.setQuery(fridgeRef , fridgeItem.class)
.build();
FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder> adapter
= new FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull fridgeViewHolder holder, int position, @NonNull fridgeItem model) {
fridgeRef.child(currentUserID).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
if(snapshot.child("Garlic").hasChild("Ingredient")){
String itemName = "Garlic";
String itemExpiry = snapshot.child("Garlic").child("Expiry").getValue().toString();
holder.ingredName.setText(itemName);
holder.ingredExpiry.setText(itemExpiry);
}
if(snapshot.child("Onion").hasChild("Ingredient")){
String itemName = "Onion";
String itemExpiry = snapshot.child("Onion").child("Expiry").getValue().toString();
holder.ingredName.setText(itemName);
holder.ingredExpiry.setText(itemExpiry);
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@NonNull
@Override
public fridgeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ingredientrecycle, parent, false);
fridgeViewHolder viewHolder = new fridgeViewHolder(view);
return viewHolder;
}
};
myIngredientList.setAdapter(adapter);
adapter.startListening();
}
public static class fridgeViewHolder extends RecyclerView.ViewHolder{
TextView ingredName, ingredExpiry;
public fridgeViewHolder(@NonNull View itemView) {
super(itemView);
ingredName = itemView.findViewById(R.id.itemName);
ingredExpiry = itemView.findViewById(R.id.itemExpiry);
}
}
成分回收.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardElevation="10dp"
app:cardCornerRadius="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:orientation="vertical"
android:layout_weight="2">
<TextView
android:id="@+id/itemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/ingred"
android:textSize="18sp"
android:fontFamily="@font/roboto" />
<TextView
android:id="@+id/itemExpiry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/expiry"
android:textSize="16sp"
android:layout_marginBottom="16dp"
android:fontFamily="@font/roboto"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:gravity="end"
android:layout_weight="1">
<ImageView
android:id="@+id/deleteBtn"
android:layout_height="20dp"
android:layout_width="20dp"
android:src="@drawable/delete_icon"
android:layout_marginEnd="32dp"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
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"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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="615dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</FrameLayout>
FirebaseUI 中的适配器旨在为您在数据库中附加适配器的路径上显示每个直接子节点的单个子视图。
在您的情况下,您将适配器连接到/Ingredient
,因此它会为/Ingredient
的每个子节点创建一个视图,这只是hgO9joLhmfh4Wjn7xYpyqcYmNOB3
的一个子节点。在该子节点中,然后读取句柄其Garlic
和Onion
属性,但您在同一视图持有者上设置它们的值 - 因此您最终只能看到来自Onion
的值。
如果要显示/Ingredient/hgO9joLhmfh4Wjn7xYpyqcYmNOB3
的所有成分,则应将适配器连接到该路径并简化其处理以:
FirebaseRecyclerOptions<fridgeItem> options =
new FirebaseRecyclerOptions.Builder<fridgeItem>()
.setQuery(fridgeRef.child("hgO9joLhmfh4Wjn7xYpyqcYmNOB3") , 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 = "Garlic"; TODO:
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);
fridgeViewHolder viewHolder = new fridgeViewHolder(view);
return viewHolder;
}
};
myIngredientList.setAdapter(adapter);
adapter.startListening();
您仍然需要从此处的数据库中获取itemName
。如果这还不在你的fridgeItem
类中,你可以用类似getRef(position).getKey()
iirc的东西来获得它。
如果您想显示所有用户的所有成分,这不符合 FirebaseUI 中适配器的逻辑,您最好创建自己的适配器。
- 像以前一样将侦听器附加到
/Ingredients
。 - 循环遍历数据快照的
getChildren()
以获取每个用户的快照。 - 循环访问每个用户快照的子项,以获取各个成分。
- 将每种成分的数据添加到数组列表中。
- 在该阵列列表上创建适配器
您没有将条件放在 foreach 循环中
@Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<fridgeItem> option
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
if(snapshot.child("Garlic").hasChild("Ingredient")){
String itemName = "Garlic";
String itemExpiry = snapshot.child("Garlic").child("Expiry").getValue().toString();
holder.ingredName.setText(itemName);
holder.ingredExpiry.setText(itemExpiry);
}
if(snapshot.child("Onion").hasChild("Ingredient")){
String itemName = "Onion";
String itemExpiry = snapshot.child("Onion").child("Expiry").getValue().toString();
holder.ingredName.setText(itemName);
holder.ingredExpiry.setText(itemExpiry);
}
}
}