如何将两个数据子项检索到 recyclerview?

Posted

技术标签:

【中文标题】如何将两个数据子项检索到 recyclerview?【英文标题】:How to retrieve two data child to recyclerview? 【发布时间】:2021-08-12 10:32:23 【问题描述】:

我正在我的大学从事一个 android 项目。我有一个这样的 Firebase 实时数据库。

我有一个 recyclerview,其中包含来自两个孩子的数据:泵和传感器(土壤水分)。一般来说,它看起来像这样(在一张卡片中):

TextView (id:sensor) (名称来自传感器-> soilMoisture) TextView (id:moisture)(来自传感器的水分-> soilMoisture) Textview (id:pump)(来自泵的名称) TextView (id:auto)(来自泵的自动)

(这不是不同类型的视图,它只是一个卡片视图,但需要来自两个孩子的数据)。 但我只能将一个孩子从 Firebase 检索到我的适配器。我一次只能显示泵名称、汽车(或传感器)。

这是我的代码:

ActivityPump.java

package com.example.gardbot;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.FirebaseDatabase;

public class ActivityPump extends AppCompatActivity 
    RecyclerView recview;
    myAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_controlpump);
        recview=(RecyclerView)findViewById(R.id.recview);
        recview.setLayoutManager(new LinearLayoutManager(this));

        FirebaseRecyclerOptions<model> options = new FirebaseRecyclerOptions.Builder<model>()
                        .setQuery(FirebaseDatabase.getInstance().getReference().child("pump"), model.class).build();

        adapter= new myAdapter(options);
        recview.setAdapter(adapter);
    

    @Override
    protected void onStart() 
        super.onStart();
        adapter.startListening();
    

    @Override
    protected void onStop() 
        super.onStop();
        adapter.stopListening();
    


model.java

package com.example.gardbot;

public class model 
    String name,auto,waterLevel;

    model()
    
    

    public model(String name, String auto, String waterLevel) 
        this.name = name;
        this.auto = auto;
        this.waterLevel=waterLevel;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getAuto() 
        return auto;
    

    public void setAuto(String auto) 
        this.auto = auto;
    

    public String getWaterLevel() 
        return waterLevel;
    

    public void setWaterLevel(String waterLevel) 
        this.waterLevel = waterLevel;
    


myAdapter.java

package com.example.gardbot;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.SwitchCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;

import org.jetbrains.annotations.NotNull;

public class myAdapter extends FirebaseRecyclerAdapter<model,myAdapter.myviewholder> 

    public myAdapter(@NonNull @NotNull FirebaseRecyclerOptions<model> options) 
        super(options);
    

    @Override
    protected void onBindViewHolder(@NonNull @NotNull myviewholder holder, int position, @NonNull @NotNull model model) 
        holder.pump.setText(model.getName());
        holder.pump.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                if (holder.pump.isChecked())
                
                    holder.linear.setVisibility(View.VISIBLE);
                
                else
                
                    holder.linear.setVisibility(View.GONE);
                
            
        );
        

        ;
    
    @NonNull
    @NotNull
    @Override
    public myviewholder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) 
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.singlerow, parent,false);
        return new myviewholder(view);
    


    class myviewholder extends RecyclerView.ViewHolder
    
        CheckBox pump;
        LinearLayout linear;
        SwitchCompat switchstate;
        public myviewholder(@NonNull @NotNull View itemView) 
            super(itemView);
            pump=(CheckBox)itemView.findViewById(R.id.pump);
            linear=(LinearLayout)itemView.findViewById(R.id.info);
            switchstate=(SwitchCompat)itemView.findViewById(R.id.switchstate);
        
    


如何将数据从传感器 (Firebase) 获取到 recyclerview(连同泵)? (在一个回收站视图中显示来自 2 个孩子的两个数据)

【问题讨论】:

我不明白你想要什么。我的理解是你想获取并显示泵和传感器数据。如果您只是显示数据,那么您必须添加另一个文本视图来显示传感器数据。如果您想要一个文本视图来显示两件事,那么您应该像字符串一样连接。否则它会覆盖值。 这段代码中到底有什么不符合您的预期?告诉我们共享代码有什么问题。你有什么错误吗? 抱歉没有仔细描述。我的意思是我也有用于泵和传感器的 TextView(4 TextView)。但我只能将一个数据子项(从适配器)获取到 recyclerview。我有 2 个 TextView 用于泵,另外 2 个用于传感器,但我一次只能显示 2 个泵的 TextView(或 2 个传感器)(我为传感器创建了另一个适配器)。我的意思是我不知道如何在 Recyclerview 中同时显示泵和传感器(土壤水分)数据(不提及它们之间的关系)和 TextView。我可能无法正确理解它,或者你能告诉我另一种正确的方法吗? 【参考方案1】:

您正在使用 FirebaseUI 库中的适配器。此库中的所有适配器都构建为仅显示数据库中单个路径下的节点。因此它们可以显示sensor 的子节点 pump 的子节点,但不能在单个列表中显示两个节点的子节点。

您要么必须将数据结构更改为具有单个平面节点列表,要么必须创建自己的适配器。

【讨论】:

【参考方案2】:

您可以使用ValueEventListener 并过滤泵数据,直到找到匹配的pumpsensor

为此,您需要输入此代码(但您需要设置传感器 ID,例如:代替“s0001”,输入“0001”):

FirebaseDatabase.getInstance().getReference("pump").child("p" + model.getSensorId()).addValueEventListener(new ValueEventListener() 
   @Override
    public void onDataChange(DataSnapshot dataSnapshot) 
        String waterLevel = dataSnapshot.child("waterLevel").getValue().toString();
    

    @Override
    public void onCancelled(DatabaseError databaseError) 
 
    
);

并在模型中添加一个变量:

String sensorId;

然后将以下内容添加到传感器数据中:sensorId

【讨论】:

以上是关于如何将两个数据子项检索到 recyclerview?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用随机键从 Firebase 数据库中检索子项到 Android 的回收站视图中?

如何从 fire-base 检索数据到新活动中单击 RecyclerView

将数据从 Firebase 检索到嵌入在 Fragment 上的 RecyclerView

如何根据 Firebase 实时数据库中的“设备”子项在 RecyclerView 中显示数据“用户设备”设备名称

如何在 Adapter 类的 RecyclerView 中提供子项的条件可见性?

如何将两个适配器设置为一个 RecyclerView?