在Firestore中获取数据后,卡未更新

时间:2020-08-07 10:20:49

标签: java android firebase android-recyclerview google-cloud-firestore

我正在尝试为库存管理系统编写一个应用程序,我需要做的一件事是能够显示可以单击的类别列表,然后将您带到该目录中的产品类别。我将CardView和RecyclerView一起使用,它们都作用于片段上(就像我在使用导航抽屉一样)。如果传递了预定义的ArrayList,我能够使卡成功显示,但是当我现在从Firestore中获取数据时,所有卡都不想出现,但是我仍然使用相同的ArrayList,但是数据只是来自不同的来源。我仍然是Android的初学者,如果有人可以帮助我,我将非常感谢。这是我的Fragment类代码。

package com.example.drawerplayground;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;


import java.util.ArrayList;
import java.util.HashMap;

public class InventoryFragment extends Fragment {

    private TextView tv;
    private HashMap<String, Object> categories;
    private ArrayList<String> cats;
    private FirebaseFirestore db;
    private InventoryAdapter adapter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        cats = new ArrayList<>();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View inventoryView = inflater.inflate(R.layout.fragment_inventory, container, false);
        RecyclerView recyclerView = (RecyclerView) inventoryView.findViewById(R.id.recycler_view);
        adapter = new InventoryAdapter(getContext(), cats);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
        recyclerView.setLayoutManager(gridLayoutManager);
        recyclerView.setAdapter(adapter);
        getCategories();
        return inventoryView;
    }

    public void getCategories()
    {
        cats = new ArrayList<>();
        db = FirebaseFirestore.getInstance();
        db.collection("categories")
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if(task.isSuccessful())
                        {
                            for(QueryDocumentSnapshot document : task.getResult())
                            {
                                cats.add(document.get("categoryName").toString());
                                Log.d("fragment", document.get("categoryName").toString());
                            }
                        }
                    }
                });
        adapter.notifyDataSetChanged();
    }


}

我尝试对适配器使用notifyDataSetChanged()方法,还尝试通过单独的功能执行数据提取,如您在上面看到的那样。

-编辑- 在下面,您可以看到关于数据库结构的基本概念,我有一个类别的集合,每个文档都是不同的类别,每个文档将包含一个id和categoryName字段。目前这是一个非常基本且很小的结构,因为我的目的是在开始项目本身之前先尝试一下潜在的功能。 enter image description here

1 个答案:

答案 0 :(得分:2)

我注意到您正在呼叫adapter.notifyDataSetChanged(),但是我找不到您实际上在向适配器提供猫的最新列表的地方。

您应该调整适配器并进行以下更改-

添加setCatList()方法

public void setCatList(List<String> catList) {
    this.catList= catList;
    notifyDataSetChanged();
}

修改您的getItemCount()方法

@Override
public int getItemCount() {
    if (catList!= null)
        return catList.size();
    else
        return 0;
}

因此您的InventoryAdapter的结构如下-

public class InventoryAdapter extends RecyclerView.Adapter<InventoryAdapter.CustomViewHolder> {

    private Context context;
    private List<String> catList;

    public InventoryAdapter(Context context) {
        this.context = context;
    }
    
    public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new CustomViewHolder(LayoutInflater.from(context).inflate(R.layout.cat_item_layout, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) {
    // setup binding of views
    }

    public void setCatList(List<String> catList) {
        this.catList= catList;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        if (catList!= null)
            return catList.size();
        else
            return 0;
    }

    //inner class of CustomViewHolder
}

然后,您无需在new ArrayList<>()onCreate()下创建 onCreateView()。这就是创建适配器的方式-

adapter = new InventoryAdapter(getContext());

getCategories()将如下所示-

public void getCategories()
{
    db = FirebaseFirestore.getInstance();
    db.collection("categories")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if(task.isSuccessful())
                    {
                        List<String> cats = new ArrayList();
                        for(QueryDocumentSnapshot document : task.getResult()){
                            cats.add(document.get("categoryName").toString());
                            Log.d("fragment", document.get("categoryName").toString());
                        }
                        adapter.setCatList(cats ); //simply give updated cats list to recycle adapter
                    }
                }
            });
}

无需调用 adapter.notifyDataSetChanged(),因为在适配器的setCatList()方法下将需要小心。

如果要保留catList,则可以进行if检查,从而相应地setCatList()进行修改,如下所示-

public void setCatList(List<String> catList) {
    if(this.catList!=null){
        if(this.catList.size()!=0){
            //there is some cat item inside already, take action accordingly 
        }
        else
            this.catList= catList;
    }
    else{
        this.catList= catList;
    }
   
    notifyDataSetChanged();
}

快乐编码!