2017-02-10 18 views
1

У меня есть эта функция поиска для поиска конкретных пользователей с использованием базы данных firebase с использованием GeoFire.Как получить доступ (изменить, добавить элементы) в ArrayList/Collection в классе Inner в java?

Что я хочу сделать:

В GeoQueryEventListener() & onKeyEntered, я хочу, чтобы добавить каждый ключ найден на ArrayList (за пределами onKeyEntered()).

У меня есть проблема:

Когда я печатаю его внутри onKeyEntered(), это работает. Но как только я выйти из GeoQueryEventListener(), keysGeolocated пуст

public ArrayList<User> search(GeoFire geoFire, int day, final boolean isBartender, double latitude, double longitude, double radius, double rate, double nightlyRate, double hourlyRate, final String speciality){ 

    keysGeolocated = new ArrayList<>(); 
    FirebaseDatabase database = FirebaseDatabase.getInstance(); 
    root = database.getReference(); 
    DatabaseReference usersRef = root.child("Users"); 

    GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), radius); 
    geoQuery.addGeoQueryEventListener(new MyGeoListener(keysGeolocated)); 

    System.out.println("KEYS GEOLOCATED" + keysGeolocated); 

    final ArrayList<User> result = new ArrayList<>(); 

    for(String key : keysGeolocated){ 

     Query queryByLocation = usersRef.orderByKey().equalTo(key); 
     DatabaseReference refToLocationQuery = queryByLocation.getRef(); 

     if(checkRefNull(refToLocationQuery) == true) { 
      System.out.println("QUERY BY LOCATION NULL"); 
      continue; 
     } 

     Query queryByTypeOfUser = refToLocationQuery.orderByChild("isBarTender").equalTo(isBartender); 
     DatabaseReference refToTypeOfUserQuery = queryByTypeOfUser.getRef(); 

     if(checkRefNull(refToTypeOfUserQuery) == true) { 
      System.out.println("QUERY BY TYPE NULL"); 
      continue; 
     } 
     Query queryByRate = refToTypeOfUserQuery.orderByChild("rate").startAt(rate); 
     DatabaseReference refToRateQuery = queryByRate.getRef(); 

     if(checkRefNull(refToRateQuery) == true) { 
      System.out.println("QUERY BY RATE NULL"); 
      continue; 
     } 

     DatabaseReference finalRef = null; 

     if(isBartender == true){ 

      if(nightlyRate == 0){ 
       Query queryByPrice = refToRateQuery.orderByChild("nightlyRate").endAt(nightlyRate); 
       finalRef = queryByPrice.getRef(); 
      } 
      else if(hourlyRate == 0){ 
       Query queryByPrice = refToRateQuery.orderByChild("hourlyRate").endAt(hourlyRate); 
       finalRef = queryByPrice.getRef(); 
      } 

      //TODO Impelement checks for available dates 

     } 
     else{ 
      finalRef = refToRateQuery; 
     } 

     finalRef.addValueEventListener(new ValueEventListener() { 

      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 

       if(dataSnapshot.getValue()!=null){ 

        User userFound = dataSnapshot.getValue(User.class); 

        if(isBartender == true){ 
         Bartender barTenderFound = (Bartender) userFound; 
         if(speciality != null){ 
          if(barTenderFound.getSpeciality().contains(speciality)){ 
           result.add(barTenderFound); 
          } 
         } 
         else{ 
          result.add(barTenderFound); 
         } 
        } 
        else{ 
         result.add(userFound); 
        } 
       } 
      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 

    } 

    return result; 
} 

public boolean checkRefNull(DatabaseReference ref){ 

    final boolean[] result = new boolean[1]; 
    result[0] = false; 

     ref.addValueEventListener(new ValueEventListener() { 


      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       System.out.println("TEST1"); 
       if(dataSnapshot.getValue()==null){ 
        result[0] = true; 
        System.out.println("TESTTEST"); 
       } 
       else{ 
        System.out.println("TESTTEST TRUE" + dataSnapshot.getValue()); 
       } 
      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
    }); 

    return result[0]; 
} 

public void setBarTender(boolean barTender){ 

    this.barTender = barTender; 
} 
} 

class MyGeoListener implements GeoQueryEventListener { 

private ArrayList<String> keysGeolocated; 

MyGeoListener(ArrayList<String> keysGeolocated){ 
    this.keysGeolocated = keysGeolocated; 
} 

@Override 
public void onKeyEntered(String key, GeoLocation location) { 
    keysGeolocated.add(key); 
} 

@Override 
public void onKeyExited(String key) { 

} 

@Override 
public void onKeyMoved(String key, GeoLocation location) { 

} 

@Override 
public void onGeoQueryReady() { 

} 

@Override 
public void onGeoQueryError(DatabaseError error) { 

} 
} 
+2

Измените область действия. Не может быть локальным для этого метода. – duffymo

+0

Вы принимаете мгновенные результаты от слушателя. Если это было синхронно, ваш вызов распечатает список. К сожалению, этот слушатель является асинхронным. Он будет добавлять данные внутри списка, когда и когда срабатывают события. Вы будете видеть работу печати только через некоторое время. – Kushan

+0

Это должен быть анонимный класс? : -} – efekctive

ответ

1

сделать класс, который расширяет, что слушатель и переопределить все методы

class MyGeoListener extends GeoQueryEventListener{ 

    private ArrayList<String> keysGeolocated; 

    MyGeoListener(ArrayList<String> keysGeolocated){ 
      this.keysGeolocated = keysGeolocated; 
    } 

    @Override 
    public void onKeyEntered(String key, GeoLocation location) { 
     keysGeolocated.add(key); 
     System.out.println("1111111111 : "+keysGeolocated); 
     System.out.println("2222222222 : "+key); 
    } 

    @Override 
    public void onKeyExited(String key) { 

    } 

    @Override 
    public void onKeyMoved(String key, GeoLocation location) { 

    } 

    @Override 
    public void onGeoQueryReady() { 

    } 

    @Override 
    public void onGeoQueryError(DatabaseError error) { 

    } 
} 

Теперь использовать этот класс следующим образом:

geoQuery.addGeoQueryEventListener(new MyGeoListener(keysGeolocated)); 

Следующий вызов будет всегда печатать никакие значения в списке, поскольку слушатель является асинхронным и занимает время, чтобы заполнить список.

Попробуйте помещать печать внутри обработчика, после того как она установлена ​​на 30000 миллисекунд. Вероятно, вы увидите записи в списке, так как к тому времени события слушателя должны были быть запущены.

Поскольку arraylist изменен и вы передаете его ссылку, аррайалист в аргументе также будет изменен, когда вызывает прослушиватель.

Удачи и дайте мне знать, если у вас все еще есть проблемы.

+0

Большое спасибо за ваш быстрый ответ! К сожалению, он по-прежнему не работает: s – Louis

+0

в чем проблема? – Kushan

+0

Я обновил сообщение с текущим кодом. Когда вы печатаете keysGeolocated, у меня есть: System.out: KEYS GEOLOCATED [] все еще ..: s – Louis