Как я могу изменить переменную внешнего класса от анонимного внутреннего класса? - PullRequest
0 голосов
/ 29 августа 2018

У меня есть ArrayList для базы данных, и у меня есть функция getArrayList, которая ссылается на базу данных и возвращает список. Проблема в том, что я не могу сохранить массив, потому что получаю его из внутреннего класса.

* ArrayList wait_list определен вне

 private ArrayList<FirebaseUser> getWaitingList (String uid){
    database.child("books").child(""+itemNum+1)
    .addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot d:dataSnapshot.getChildren()){
                if(d.getKey().equals("waiting list"));
                        GenericTypeIndicator<ArrayList<FirebaseUser>> t = new GenericTypeIndicator<ArrayList<FirebaseUser>>() {};
                        waiting_list = d.getValue(t);// this is the problem
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    return waiting_list; //I beleive that waiting_list is still null here
}

1 Ответ

0 голосов
/ 29 августа 2018

Вы правы, список по-прежнему равен нулю, потому что вы никогда не ожидаете результатов Firebase по сети, ваш код только устанавливает прослушиватель, а затем сразу возвращает пустой список.

Вместо этого блокирующего вызова из вашего метода

someList = getWaitingList (String uid);
// use someData

Вы должны делать что-то вроде этого асинхронного вызова

// Do NOT make a list variable outside of this
getWaitingList (String uid, new Listener() {
    @Override onData(List someData) {
        // use someData, for example, update a listview 
    } 
});
// do NOT reference the list outside of the listener block method 

Как говорится,

Определить интерфейс

interface UserListListener {
    void onUsers(List<FirebaseUser> users);
} 

Добавьте параметр в метод и сделайте его недействительным, потому что вы вернетесь из интерфейса

void getWaitingList (String uid, final UserListListener listener) {
   ... 

И остальная часть кода Firebase, возможно, в порядке, но вы зацикливаетесь на вещах, поэтому я думаю, что вы хотите добавить в список, а не просто назначить один, но в любом случае, вот и остальная часть метода, использующего Обратный звонок

GenericTypeIndicator<ArrayList<FirebaseUser>> t = new GenericTypeIndicator<ArrayList<FirebaseUser>>() {};
// Move the list inside this listener 
List<FirebaseUser> waitingList = new ArrayList<>();
for (DataSnapshot d:dataSnapshot.getChildren()){
    if(d.getKey().equals("waiting list")) {
        waitingList = d.getValue(t);
    }
}
listener.onUsers(waitingList); // end of the method

Тогда внешний вызов метода отвечает за реализацию класса слушателя и получение данных.

Вы также захотите реализовать onCancelled; Рекомендуется сначала реализовать это, потому что именно там вы будете получать уведомления об ошибках Firebase - не оставляйте это поле пустым

...