我必须在我的应用程序集群功能中实现从服务器加载的数据。我已经使用改造库成功地在地图中显示了数据,但是我尝试进行聚类并且它不起作用。我在互联网上关注了 android 文档和一些教程,但我对自己做错了什么感到非常困惑。这是我的代码:
Callback<List<Vehicle>> callback = new Callback<List<Vehicle>>() {
@Override
public void onResponse(@NotNull Call<List<Vehicle>> call, Response<List<Vehicle>> response) {
if (response.isSuccessful()) {
vehicles = response.body();
assert vehicles != null;
try {
mGoogleMap.clear();
for (int i = 0; i < vehicles.size(); i++) {
PortalMetaData metaData = vehicles.get(i).getPortalMetaData();
float x = metaData.getLocations().getX();
float y = metaData.getLocations().getY();
float offset = i / 60f;
x = x + offset;
y = y + offset;
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(x, y);
markerOptions.position(latLng);
markerOptions.title(metaData.getPortalName());
markerOptions.snippet("Id: " + vehicles.get(i).getId());
mGoogleMap.addMarker(markerOptions);
cameraConfigurations(latLng);
mClusterManager = new ClusterManager<>(getApplicationContext(), mGoogleMap);
ClusterItem location = new ClusterItem(x, y);
mClusterManager.addItem(location);
CustomClusterRenderer renderer = new CustomClusterRenderer(getApplicationContext(), mGoogleMap, mClusterManager);
//mClusterManager.setAlgorithm(new NonHierarchicalDistanceBasedAlgorithm<>());
mClusterManager.setRenderer(renderer);
mClusterManager.cluster();
mGoogleMap.setOnCameraIdleListener(mClusterManager);
mGoogleMap.setOnMarkerClickListener(mClusterManager);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 5.0f));
}
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
} else {
System.out.println(response.body());
Log.e(TAG, "Error: data cannot be loaded");
}
我已调试,一切似乎都很好。我的自定义渲染器是这样的:
private static final int MIN_CLUSTER_SIZE = 1;
private final IconGenerator mClusterIconGenerator;
private Context mContext;
private ClusterManager<ClusterItem> mClusterManager;
Map<Cluster<ClusterItem>, Marker> clusterMarkerMap = new HashMap<>();
public CustomClusterRenderer(Context context, GoogleMap map, ClusterManager<ClusterItem> clusterManager) {
super(context, map, clusterManager);
mContext = context;
mClusterManager = clusterManager;
mClusterIconGenerator = new IconGenerator(context);
}
@Override
protected void onBeforeClusterItemRendered(@NonNull ClusterItem item, @NonNull MarkerOptions markerOptions) {
BitmapDescriptor mBitmapDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA);
markerOptions.icon(mBitmapDescriptor);
}
@Override
protected void onClusterItemRendered(@NonNull ClusterItem clusterItem, @NonNull Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
}
@SuppressLint("UseCompatLoadingForDrawables")
@Override
protected void onBeforeClusterRendered(@NonNull Cluster<ClusterItem> cluster, @NonNull MarkerOptions markerOptions) {
final Drawable mClusterIcon = mContext.getResources().getDrawable(ic_baseline_directions_car_24);
mClusterIcon.setColorFilter(mContext.getResources().getColor(android.R.color.holo_orange_light), PorterDuff.Mode.SRC_ATOP);
mClusterIconGenerator.setBackground(mClusterIcon);
if (cluster.getSize() > MIN_CLUSTER_SIZE) {
mClusterIconGenerator.setContentPadding(40, 20, 0, 0);
} else {
mClusterIconGenerator.setContentPadding(30, 20, 0, 0);
}
Bitmap mIcon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(mIcon));
}
@Override
protected boolean shouldRenderAsCluster(@NonNull Cluster<ClusterItem> cluster) {
return cluster.getSize() > MIN_CLUSTER_SIZE;
}
@Override
protected void onClusterRendered(@NonNull Cluster<ClusterItem> cluster, @NonNull Marker marker) {
super.onClusterRendered(cluster, marker);
clusterMarkerMap.put(cluster, marker);
}
有人可以给我一些建议,说明我做错了什么,或者什么是正确设置聚类的好方法。
编辑:最后我解决了我的问题,这是我做的一个错误。我只向集群管理器添加了一个集群项目。我创建了一个新的集群项目 ArrayList,并在 for 循环中为每个项目添加了坐标。然后在 for 循环之外,我调用了 clustermanager.addItems(clusteritems) 并且正在工作。以下是我为面临此问题的任何人提供的代码:
Callback<List<Vehicle>> callback = new Callback<List<Vehicle>>() {
@Override
public void onResponse(@NotNull Call<List<Vehicle>> call, Response<List<Vehicle>> response) {
if (response.isSuccessful()) {
vehicles = response.body();
assert vehicles != null;
List<ClusterItem> clusterItems = new ArrayList<>();
try {
mGoogleMap.clear();
for (int i = 0; i < vehicles.size(); i++) {
PortalMetaData metaData = vehicles.get(i).getPortalMetaData();
float x = metaData.getLocations().getX();
float y = metaData.getLocations().getY();
float offset = i / 60f;
x = x + offset;
y = y + offset;
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(x, y);
markerOptions.position(latLng);
markerOptions.title(metaData.getPortalName());
markerOptions.snippet("Id: " + vehicles.get(i).getId());
mGoogleMap.addMarker(markerOptions);
cameraConfigurations(latLng);
mClusterManager = new ClusterManager<>(getApplicationContext(), mGoogleMap);
ClusterItem location = new ClusterItem(x, y);
mClusterManager.addItem(location);
clusterItems.add(location);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 5.0f));
}
CustomClusterRenderer renderer = new CustomClusterRenderer(getApplicationContext(), mGoogleMap, mClusterManager);
mClusterManager.addItems(clusterItems);
mClusterManager.setAlgorithm(new NonHierarchicalDistanceBasedAlgorithm<>());
mClusterManager.setRenderer(renderer);
mClusterManager.cluster();
mGoogleMap.setOnCameraIdleListener(mClusterManager);
mGoogleMap.setOnMarkerClickListener(mClusterManager);
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
} else {
System.out.println(response.body());
Log.e(TAG, "Error: data cannot be loaded");
}