[英]How to access (modify, add elements) to an ArrayList/Collection in an Inner class in java?
我有這個搜索功能,可以使用 GeoFire 使用 firebase 數據庫搜索特定用戶。
我想做的事 :
在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) {
}
}
創建一個擴展該偵聽器並覆蓋所有方法的類
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 也將被修改。
祝你好運,如果你還有問題,請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.