[英]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.