2017-02-10 78 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