java - 根据位置条件创建适配器
问题描述
我正在尝试制作如下内容:
我有一个应用程序并且我知道我的位置(例如,假设它是 4 号)。我也有一个定义的半径。我喜欢它在地图下方的适配器中显示半径内的所有结果(例如,它应该只显示 1 和 5 - 4 是我的位置,所以我不需要它显示)。
现在,想象一下我试图显示的数字是我在 Cloud Firestore 数据库中拥有的用户。为了在地图上显示它们,我需要执行查询以检查某些条件,然后检查它们是否在定义的半径内。如果它们都具有条件并且在半径范围内,我希望将它们添加到适配器中。
我使用以下代码来实现它:
db.collection("Users").document(document.getData().get( "UserID" ).toString()).collection( "Location" ).get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document2 : task.getResult()) {
Object BookLat = document2.getData().get( "Lat" );
Object BookLon = document2.getData().get( "Lon" );
float distance = CalculateDistance(Lat, Lon, BookLat, BookLon);
if (distance <=Radius){
MapPersonAdapter mapPersonAdapter = new MapPersonAdapter( LocationsActivity.this,document.getData().get( "UserID" ).toString(), distance );
lvPerson.setAdapter( mapPersonAdapter );
MapPerson mapPerson = MapPerson.Result(document.getData().get( "UserID" ).toString(), distance);
mapPersonAdapter.add( mapPerson );
mapPersonAdapter.notifyDataSetChanged();
}
}
} else {
Log.d("ERROR", "Error getting documents: ", task.getException());
}
}
});
问题从这里开始。
1)由于我需要检查每个查询的距离,我需要一个接一个地添加到我的适配器。这导致我无法将所有结果保存在某个数组中,然后插入到适配器(由于void
类async task
)。
2)我需要使用其中的变量(UserID,distance
)制作适配器 MapPersonAdapter,因为在viewHolder
我需要使用的适配器内部:
viewHolder.tvPersonName.setText(person.getPersonName( personID ));
定义在:
public static String getPersonName(String personID) {
// PART FOR DISPLAYING PROFILE NAME//
FirebaseFirestore db = FirebaseFirestore.getInstance();
CollectionReference username = db.collection( "Users" ).document(personID).collection( "UserData" );
username.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
personname = document.getString( "username" );
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
return personname;
}
这导致我必须在查询中初始化适配器。
这两个问题迫使我在查询本身内部初始化适配器,这最终导致适配器只显示最后一个结果,因为它覆盖了视图(总是返回位置 0)。
有没有办法创建这样一个在 for 循环中调用并保存所有结果的适配器?(请记住,它在异步任务中,在查询之外获取结果非常复杂)。
谢谢
解决方案
我喜欢它在地图下方的适配器中显示半径内的所有结果(例如,它应该只显示 1 和 5 - 4 是我的位置,所以我不需要它显示)。
目前无法使用地理位置查询 Cloud Firestore 数据库。Firestore 不支持 GeoPoint 查询。解决此问题的唯一方法是使用geohashes。还有一个非常有用的视频,Frank van Puffelen 详细解释了同一主题。
除此之外,如果您使用的是 Android,还有一个名为GeoFirestore 的 Android 库,可以帮助您获取特定半径内的附近位置。
此外,Firebase API 是异步的,因此您无法将从数据库中获取的数据作为方法的结果返回。一个快速解决这个问题personname
的方法是在方法内部使用 only的值,否则我建议你从这篇文章onComplete()
中查看我的 anwser 的最后一部分,其中我已经解释了如何使用自定义回调来完成它。您也可以观看此视频以更好地理解。
推荐阅读
- reactjs - 如何从 React Js 代码中取出流类型?
- python - 如何正确使用 `cv2.putText` 在视频上绘制阿拉伯文字?(Python+OpenCV)
- swiftui - 具有多个 onReceive() 处理程序的 macOS SwiftUI SceneView 似乎相互阻塞
- javascript - 找不到模块'react-bootstrap/lib/breadcrumb'
- oracle - 需要关于如何优化我的函数 PL/SQL 的建议
- swift - 强制 *new* Finder 窗口以编程方式打开
- jmeter - 从命令行在 JMeter 中生成汇总报告
- c++ - 关于#ifndef 之后的#define 宏
- python - 正则表达式对象如何在 Python 循环中工作?
- android - Android build.gradle 排除重复类