当我计算食物的平均评分时,将此值保存到它显示为 0.0 的食物对象

When I calculate an average rating of foods, save this value to an food object it displays as 0.0

在我的实时数据库 (Firebase) 中,我有两个 'collections' 一个用于 essen(食物),一个用于 bewertung(食物评级)

我尝试在我的应用程序中显示每种食物的数据,这适用于食物名称和价格 (Preis)

因此我根据控制台中显示的值计算每种食物的平均评分

但是当我尝试访问每种食物的平均值时,将其设置为 TextView,平均值为 0.0,这是默认的浮点值。 但是食物的所有其他值都正确显示(名称和价格)

这是我的片段 java class,我在其中计算平均值并设置我从 firebase 检索的所有值:

public class Aktuelle_Bewertungen_Fragment extends Fragment{


    //Elemente:
    private RecyclerView recyclerView_aktuelle_Bewertungen;


    private View aktuelleBewertungenView;

    private DatabaseReference essenRef;
    private DatabaseReference bewertungenRef;



    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        aktuelleBewertungenView =  inflater.inflate(R.layout.fragment_aktuelle_bewertungen, container, false);

        //Elemente finden:
        recyclerView_aktuelle_Bewertungen = (RecyclerView) aktuelleBewertungenView.findViewById(R.id.recyler_aktuelle_bewertungen);

        //Referenz auf essen:
        essenRef = FirebaseDatabase.getInstance().getReference().child("essen");
        //Referenz auf bewertungen:
        bewertungenRef = FirebaseDatabase.getInstance().getReference().child("bewertung");


        return aktuelleBewertungenView;
    }



    @Override
    public void onStart() {

        super.onStart();

        FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder<essen>().setQuery(essenRef, essen.class).build();
        final FirebaseRecyclerAdapter<essen, EssenViewHolder> adapter = new FirebaseRecyclerAdapter<essen, EssenViewHolder>(options) {

            @NonNull
            @Override
            public EssenViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.reihen, parent, false);
                EssenViewHolder viewHolder = new EssenViewHolder(view);

                return viewHolder;

            }

            @Override
            protected void onBindViewHolder(@NonNull final EssenViewHolder holder, final int position, @NonNull essen model) {


                final ArrayList<essen> testessen =new ArrayList<>();

                essenRef.addValueEventListener(new ValueEventListener() {

                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                        for (DataSnapshot ds : dataSnapshot.getChildren()){

                                final essen e = new essen();
                                  e.name =   ds.child("name").getValue(String.class);
                                  e.Preis = ds.child("Preis").getValue(String.class);


                            bewertungenRef.addValueEventListener(new ValueEventListener() {
                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                                    float sum = (float) 0.0;
                                    int counter = 0;


                                    for (DataSnapshot ds1 : dataSnapshot.getChildren()){
                                        if (ds1.child("eid").getValue(String.class).equals(e.name)){

                                            sum = sum + ds1.child("wert").getValue(float.class);
                                            counter ++;

                                        }
                                    }

                                    float durchschnitt = sum/counter;

                                    Log.i("durchschnitt" , " " + sum + " "+ counter + " " +durchschnitt);

                                    e.setAverage(durchschnitt);

                                    Log.i("essen wert: " , " " + e.getAverage());

                                }

                                @Override
                                public void onCancelled(@NonNull DatabaseError databaseError) {

                                }
                            });

                            testessen.add(e);

                        }


                        holder.essenName.setText(testessen.get(position).getName());
                        holder.essenPreis.setText(testessen.get(position).getPreis());

                        float test = (float) testessen.get(position).getAverage();
                        Log.i("test :" , " "+ test);
                        holder.test.setText(testessen.get(position).getAverage());

                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });
            }
        };

        recyclerView_aktuelle_Bewertungen.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView_aktuelle_Bewertungen.setAdapter(adapter);
        recyclerView_aktuelle_Bewertungen.hasFixedSize();
        adapter.startListening();
    }



    public  class EssenViewHolder extends RecyclerView.ViewHolder{

        TextView essenName, essenPreis, test;

        public EssenViewHolder (@NonNull View itemView ) {
            super(itemView);

            essenName = itemView.findViewById(R.id.reihen_name);
            essenPreis = itemView.findViewById(R.id.reihen_preis);

            test = itemView.findViewById(R.id.reihen_test);


        }


    }


}

平均计算的输出是:对于食物测试 1:

I/durchschnitt: 12.5 4 3.125 -> 12.5/4 = 3.125

对于测试 2:

I/durchschnitt: 12.5 4 3.125 -> 12.5/4 = 3.125

对于测试 3:

I/durchschnitt: 2.5 1 2.5 -> 2.5/1 = 2.5

数据库中的条目:测试 1:3 + 3+ 4 +2.5 = 12.5 测试 2:3.5+3.5+3+2.5= 12.5 测试 3:2.5 = 2.5 计算似乎工作正常...

这是我的精华class:

    String name,Preis;
    float average;


    public String getName() {
        return name;
    }

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

    public String getPreis() {
        return Preis;
    }

    public void setPreis(String preis) {
        Preis = preis;
    }

    public float getAverage() {
        return average;
    }

    public void setAverage(float average) {
        this.average = average;
    }


    public essen (String name, String Preis, float average){
        this.name = name;
        this.Preis = Preis;
        this.average = average;
    }

    public essen(){}

}

这是我的 XML 布局文件,它显示在回收视图中(我删除了所有不必要的视图,因此约束可能看起来有点奇怪):

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:layout_margin="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">



            <TextView
                android:id="@+id/reihen_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:fontFamily="@font/roboto"
                android:text="Name"
                android:textColor="@color/rot"
                android:textSize="17sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.064"
                app:layout_constraintStart_toEndOf="@+id/reihen_bilder"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.149" />

            <TextView
                android:id="@+id/reihen_preis"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:fontFamily="@font/roboto"
                android:text="Preis"
                android:textColor="@color/black"
                android:textSize="17sp"
                android:textStyle="normal"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.723"
                app:layout_constraintStart_toEndOf="@+id/reihen_bilder"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.507" />



            <TextView
                android:id="@+id/reihen_test"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="TextView"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.552"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.14" />


        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

这是来自我的 Firebase 数据库的屏幕截图:

我现在看到您设置 计算数据的 onDataChange 之外的视图的平均值。这是行不通的,因为到你的 holder.test.setText(testessen.get(position).getAverage()) 运行 时,e.setAverage(durchschnitt) 还没有 运行。

任何需要数据库数据的代码都需要在该数据的 onDataChange 中,或者从那里调用。

最简单的方法是只显示嵌套 onDataChange:

内部的平均值
final ArrayList<essen> testessen =new ArrayList<>();

essenRef.addValueEventListener(new ValueEventListener() {

    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

        for (DataSnapshot ds : dataSnapshot.getChildren()){

            final essen e = new essen();
            e.name  = ds.child("name").getValue(String.class);
            e.Preis = ds.child("Preis").getValue(String.class);

            bewertungenRef.addListenerForSingleValue(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                    float sum = (float) 0.0;
                    int counter = 0;


                    for (DataSnapshot ds1 : dataSnapshot.getChildren()){
                        if (ds1.child("eid").getValue(String.class).equals(e.name)){

                            sum = sum + ds1.child("wert").getValue(float.class);
                            counter ++;

                        }
                    }

                    float durchschnitt = sum/counter;

                    Log.i("durchschnitt" , " " + sum + " "+ counter + " " +durchschnitt);

                    e.setAverage(durchschnitt);

                    Log.i("essen wert: " , " " + e.getAverage());

                    holder.essenName.setText(testessen.get(position).getName());
                    holder.essenPreis.setText(testessen.get(position).getPreis());

                    float test = (float) testessen.get(position).getAverage();
                    Log.i("test :" , " "+ test);
                    holder.test.setText(testessen.get(position).getAverage());
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    throw databaseError.toException(); // don't ignore errors
                }
            });

            testessen.add(e);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore errors
    }
});

在上面,您从 bewertungenRef 加载所有数据,而您只需要这些项目的一个子集。您还要为每次迭代重新加载该数据,这非常浪费(但应该有效)。

根据您拥有的数据量,您可能需要考虑仅加载 bewertungenRef 中需要的子节点。这意味着您有多个侦听器,这是一个很好的时机,也可以在加载所有数据后仅更新 UI 中的平均值。

看起来像这样(未经测试,因此代码可能包含小问题):

final ArrayList<essen> testessen =new ArrayList<>();

essenRef.addValueEventListener(new ValueEventListener() {

    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        float sum = (float) 0.0;
        int counter = 0;

        // these variables track how many items we need to load, and how many we've already loaded
        long essenCount = dataSnapshot.getChildrenCount();
        long loadedCount = 0;

        for (DataSnapshot ds : dataSnapshot.getChildren()){
            final essen e = new essen();
            e.name  = ds.child("name").getValue(String.class);
            e.Preis = ds.child("Preis").getValue(String.class);

            bewertungenRef.orderByChild("eid").equalTo(e.name).addListenerForSingleValue(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    for (DataSnapshot ds1 : dataSnapshot.getChildren()){
                        sum = sum + ds1.child("wert").getValue(float.class);
                        counter++;
                    }

                    if (loadedCount++ == essenCont) {
                        float durchschnitt = sum/counter;

                        e.setAverage(durchschnitt);

                        Log.i("essen wert: " , " " + e.getAverage());

                        holder.essenName.setText(testessen.get(position).getName());
                        holder.essenPreis.setText(testessen.get(position).getPreis());

                        holder.test.setText(testessen.get(position).getAverage());
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    throw databaseError.toException(); // don't ignore errors
                }
            });

            testessen.add(e);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore errors
    }
});