java - 如何在我的 RecyclerView 中显示来自 firebase 的子数据的子数据?

标签 java android firebase-realtime-database android-recyclerview firebaseui

我想显示数据库中所有类别中所有 child 的数据(添加了我的数据库外观的下图)。我正在使用需要传递 FirebaseRecyclerOptions 对象的适配器将数据添加到我的 RecyclerView。我看到一个答案,其中 DataSnapshot 用于获取子数据的子数据,我尝试使用它获取数据,当我将其登录到 logcat 时它显示给我(注释代码是我尝试使用的代码),但我不知道如何将它与我的适配器类一起使用。

这是我的数据库的样子,我想要突出显示的字段内的数据:

{
    "Category_wise": {
        "education": {
            "udemy": {     <-Return data of this child
                "companyName": "Udemy",
                ...
            },
            "khanacademy": {     <-Return data of this child
                "companyName": "Khan Academy",
                ...
            }
        },
        "technology": {
            "google": {    <-Return data of this child
                "companyName": "Google",
                ...
            },
            "facebook": {    <-Return data of this child
                "companyName": "Facebook",
                ...
            },
        ....
    }   
}

在下面的代码中,SCard 是我的模型类,SCardAdapter 是我的适配器类。

这是我要将数据添加到 recyclerview 的 fragment (HomeFragment):

public class HomeFragment extends Fragment{
    private RecyclerView recyclerView;
    private Query query;
    private SCardAdapter<SCard, SCardAdapter.ViewHolder> adapter;

    public HomeFragment() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_home, container, false);
        recyclerView = v.findViewById(R.id.search_recyclerview);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setHasFixedSize(true);

        setQueryByOrder("technology", "totalInvestors");
        fetchResult(query);

        return v;
    }

//    protected void fetchAll(){
//        final DatabaseReference reference= FirebaseDatabase.getInstance().getReference("Category_wise");
//        reference.addValueEventListener(new ValueEventListener() {
//            @Override
//            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
//                for (DataSnapshot snapshot : dataSnapshot.getChildren()){
//                    Log.i(TAG, "4321: Name of each company: " + Objects.requireNonNull(snapshot.child("companyName").getValue()).toString()
//                }
//            }
//            @Override
//            public void onCancelled(@NonNull DatabaseError databaseError) {}
//        });
//    }

    protected void setQueryByOrder(String choice, String order){
        query = FirebaseDatabase.getInstance()
                .getReference()
                .child("Category_wise").child(choice).orderByChild(order);
    }

    protected void fetchResult(Query query) {
        FirebaseRecyclerOptions<SCard> options =
                new FirebaseRecyclerOptions.Builder<SCard>()
                        .setQuery(query, new SnapshotParser<SCard>() {
                            @NonNull
                            @Override
                            public SCard parseSnapshot(@NonNull DataSnapshot snapshot) {
                                return new SCard(
                                        Objects.requireNonNull(snapshot.child("companyName").getValue()).toString()...);
                            }
                        })
                        .build();
        adapter = new SCardAdapter<>(options);
        adapter.startListening();
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onStart() {
        super.onStart();
        adapter.startListening();
    }

    @Override
    public void onStop() {
        super.onStop();
        adapter.stopListening();
    }
}

这是我的适配器类:

public class SCardAdapter<M extends SCard, V extends SCardAdapter.ViewHolder> extends FirebaseRecyclerAdapter<SCard, V> {

    FirebaseRecyclerOptions<SCard> options;
    public SCardAdapter(@Nullable FirebaseRecyclerOptions<SCard> options) {
        super(options);
        this.options = options;
    }

    @Override
    protected void onBindViewHolder(V holder, @SuppressLint("RecyclerView") final int position, SCard model) {
        holder.setName(model.getsName());
      ...
    }

    @Override
    public V onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.startup_search_card, parent, false);
        return (V) new ViewHolder(view);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        ImageView simg2;
        TextView sname, sdesc, senddate, sperraised, snoin, sminam;
        ProgressBar sraisingprogbar;
        public ViewHolder(View itemView) {
            super(itemView);
            sname = itemView.findViewById(R.id.sname);
          ...
        }

        public void setName(String string) {
            sname.setText(string);
        }
      ...
    }
}

最佳答案

首先,您需要创建 2 个循环,因为您的 json 看起来像那样,并将它们存储在 arrayList 中。您应该在 arrayList 中获取所有数据。

FirebaseDatabase.getInstance().getReference().child("Category_wise").addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()) {
            ArrayList<Scard> sCardList = new ArrayList<Scard>();
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                if (snapshot.exists()){
                    for (DataSnapshot shot : snapshot.getChildren()){
                        if (shot.exists()){
                            final Scard scard = shot.getValue(Scard.class);
                            if (scard != null){
                                sCardList.add(scard);
                            }
                        }
                    }
                }
            }
            final ScardAdapter scardAdapter = new ScardAdapter(sCardList);
            recyclerView.setAdapter(scardAdapter);
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
    }
});

接下来您需要创建自己的适配器。您也可以在 Google 上搜索以获取更多信息。但你会明白这一点。

public class ScardAdapter extends RecyclerView.Adapter<ScardViewHolder> {
    private ArrayList<Scard> sCardList;
    public ScardAdapter(final ArrayList<Scard> sCardList) {
        this.sCardList = sCardList;
    }
    @NonNull
    @Override
    public ScardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.scard_item, parent, false);
        return new ScardViewHolder(view);
    }
    @Override
    public void onBindViewHolder(@NonNull final ScardViewHolder holder, final int position) {
        final Scard model = sCardList.get(position);
        holder.getTvCompanyName.setText(model.getCompanyName);
    }
    @Override
    public int getItemCount() {
        return sCardList.size();
    }
}

关于java - 如何在我的 RecyclerView 中显示来自 firebase 的子数据的子数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71755481/

相关文章:

java - 在 Eclipse 中查找具有给定参数类型的方法引用

java - 由于 AsyncTask onPostExecute(),ArrayAdapter<String> 中出现 Android NullPointerException

java - 获得权限后如何启动应用程序?

java - if-else 的代码约定,用于 Java 中的语句

java - 为什么这个程序不终止?

java - 如何在 firebase android 中查询类似云函数中的数据库触发器

java - 即时更新 UI

java - 用空数据拆分字符串

android - 没有得到电话号码

java - 如何在 onDataChange + Glide 循环 "for"继续之前等待图像加载?