使用Firebase和Android时,如何在Android中通过方法调用更改数组值

yftpprvb  于 2022-12-28  发布在  Android
关注(0)|答案(1)|浏览(69)

我在Android中有以下方法(用Java实现):

public  static void getInformationWhenInfoButtonIsPressed (FirebaseRatingCallback callback,float [] ratingValue,  String item) {
        
              DatabaseReference rootRef_Firebase;
              rootRef_Firebase = FirebaseDatabase.getInstance(DataBaseEntries.FIREBASE_URL).getReference();
                rootRef_Firebase
                        .child(DataBaseEntries.FIREBASE_NODE_RATINGS_AGGREGATED)
                        .orderByChild(DataBaseEntries.FIREBASE_NAME)
                        .equalTo(item)
                        .addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                int numberOfRatingsOverall = 0;
                                double tempScoreOverall =0;
                                for (DataSnapshot ds: dataSnapshot.getChildren()) {
                                    float averageRatingOfCurrentDrink = 0;
                                    int numberOfRatingsCurrentDrink = 0;
        
                                    if (ds.child(DataBaseEntries.FIREBASE_AVERAGE_RATING).getValue(Float.class)!=null) {
                                        averageRatingOfCurrentDrink= ds.child(DataBaseEntries.FIREBASE_AVERAGE_RATING).getValue(Float.class);
                                    }
        
                                    if (ds.child(DataBaseEntries.FIREBASE_NUMBER_OF_RATINGS).getValue(Integer.class)!=null) {
                                        numberOfRatingsCurrentDrink = ds.child(DataBaseEntries.FIREBASE_NUMBER_OF_RATINGS).getValue(Integer.class);
                                        numberOfRatingsOverall=  numberOfRatingsOverall + numberOfRatingsCurrentDrink ;
                                    }
                                    tempScoreOverall = tempScoreOverall + numberOfRatingsCurrentDrink * averageRatingOfCurrentDrink;
        
        
                                }
        
                                ratingValue[0] = (float) (tempScoreOverall/numberOfRatingsOverall);
        
                            }
        
                            @Override
                            public void onCancelled(@NonNull DatabaseError error) {
                                throw error.toException();
                            }
                        });
        
        
        
        
        
                ratingValue[0] = (float) (Math.round(ratingValue[0] * 10.0) / 10.0);
        
            }

在同一个类中,我有以下接口:

public interface FirebaseRatingCallback {
    void onCallBackRating (boolean dataIsReadFromFirebase); }

这个方法应该改变引用数据类型数组ratingValue[0]的值。不幸的是Firebase实时数据库是异步工作的,所以我不得不使用回调函数,我使用FirebaseRatingCallback callback。但是我不知道如何使用ValueEventListener来完成这个任务,就像我在这个例子中所做的那样。我知道如何用OnCompleteListener来做这件事,因为你有public void onComplete(@NonNull Task<Void> task) {方法,当我有ValueEventListener时,我不能用它。
因此,我尝试添加以下内容,但这不起作用:

public  static void getInformationWhenInfoButtonIsPressed (FirebaseRatingCallback callback,float [] ratingValue,  String item) {
    
        DatabaseReference rootRef_Firebase;
        rootRef_Firebase = FirebaseDatabase.getInstance(DataBaseEntries.FIREBASE_URL).getReference();
        rootRef_Firebase
                .child(DataBaseEntries.FIREBASE_NODE_RATINGS_AGGREGATED)
                .orderByChild(DataBaseEntries.FIREBASE_NAME)
                .equalTo(item)
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        int numberOfRatingsOverall = 0;
                        double tempScoreOverall =0;
                        for (DataSnapshot ds: dataSnapshot.getChildren()) {
                            float averageRatingOfCurrentDrink = 0;
                            int numberOfRatingsCurrentDrink = 0;
    
                            if (ds.child(DataBaseEntries.FIREBASE_AVERAGE_RATING).getValue(Float.class)!=null) {
                                averageRatingOfCurrentDrink= ds.child(DataBaseEntries.FIREBASE_AVERAGE_RATING).getValue(Float.class);
                            }
    
                            if (ds.child(DataBaseEntries.FIREBASE_NUMBER_OF_RATINGS).getValue(Integer.class)!=null) {
                                numberOfRatingsCurrentDrink = ds.child(DataBaseEntries.FIREBASE_NUMBER_OF_RATINGS).getValue(Integer.class);
                                numberOfRatingsOverall=  numberOfRatingsOverall + numberOfRatingsCurrentDrink ;
                            }
                            tempScoreOverall = tempScoreOverall + numberOfRatingsCurrentDrink * averageRatingOfCurrentDrink;
    
    
                        }
                        public void onComplete(@NonNull Task<Void> task) {
                            ratingValue[0] = (float) (tempScoreOverall/numberOfRatingsOverall);
                            callback.onCallBackRating(true);
                        }
    
    
    
                    }
    
                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {
                        throw error.toException();
                    }
                });
    
    
}

有人知道怎么做吗?

vwoqyblh

vwoqyblh1#

我知道写入数据库时如何执行此操作,但不知道从数据库中读取内容时如何执行此操作。
最简单的解决方案是在查询对象上调用get(),一旦操作完成,就更新LiveData对象,然后观察UI中的变化。
来自Query #get()的文档:
执行查询并将结果作为QuerySnapshot返回。
因此,一旦查询完成,即使数据库发生更改,也不会有其他未来事件,因此在查询完成后,不会有任何东西影响您的UI。

    • 编辑:**

没有LiveData是否无法做到这一点?
还有其他方法可以做到这一点,但这是迄今为止最简单的一种。不建议再使用回调。
使用LiveData时,我需要大量代码,因为我还需要2个额外的类(ViewModel和LiveData类)。
这有什么问题?这就是编程。至于ViewModel,这是Android团队推荐的构建应用程序的方式。
不要对LiveData和ViewModel做一些全新的事情,因为这也会花费太多的时间,并且会因为许多类而增加复杂性。
这不会花太多时间。只需要几分钟。一旦你理解了这些概念,你就会成为一个更好的Android开发者。不要害怕学习新东西。
P. S. Java仍然是一门很棒的语言,但是对于Android开发来说,我推荐Kotlin,你试图实现的东西可以用Kotlin用单行代码写出来。

相关问题