2017-02-10 76 views
1

我有這個搜索功能,使用GeoFire搜索使用Firebase數據庫的特定用戶。如何訪問(修改,添加元素)到Java中的Inner類中的ArrayList/Collection?

我想要做什麼:

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是可變的,並且您傳遞它的引用,所以參數中的arraylist也將在偵聽器調用時進行修改。

祝你好運,讓我知道你是否仍然有問題。

+0

非常感謝您的快速回答!不幸的是,它仍然不起作用:s – Louis

+0

現在有什麼問題? – Kushan

+0

我已經使用當前的代碼更新了帖子。當打印關鍵字Geolocated時,我得到:System.out:KEYS GEOLOCATED [] still ..:s – Louis