我有一个地图片段,由我使用自定义群集渲染器extends DefaultClusterRenderer
配置的Google群集管理器处理。
我已经过度强调了onBeforeClusterItemRendered
和onBeforeClusterRendered
功能,以便能够显示我的照片:
现在,如果用户放大,则渲染不在可见区域内的项目是没有意义的。 很容易发现物品是否在可见区域:
private Boolean isInBounds(LatLng position) {
return map.getProjection().getVisibleRegion().latLngBounds.contains(position);
}
但如果我跳过渲染,如果该项当前不可见,则当用户在地图上滚动时它将为空。
那么,如果用户滚动以及如何重新渲染不在可见边界内的项目,谁知道如何获取事件? (从可见到非可见的转换,反之亦然)?
(抱歉我的英语不好)
答案 0 :(得分:4)
这是我的解决方案。它工作得很好,只渲染可见的项目。 我使用相机更改的侦听器重新渲染现在可见的项目:
private void onBeforeClusterOrClusterItemRendered(final Cluster<MediaItem> cluster, final MediaItem mediaItem, final MarkerOptions markerOption
if(!isAdded())
return;
// In visible area?
Marker marker = cluster == null ? getMarker(mediaItem) : getMarker(cluster);
Boolean isInBounds = isInBounds(marker != null ? marker.getPosition() : mediaItem.getPosition(), null);
if(isInBounds) {
// ...
}
}
private Boolean isInBounds(LatLng position, LatLngBounds latLngBounds) {
return (latLngBounds == null ? mMap.getProjection().getVisibleRegion().latLngBounds : latLngBounds).contains(position);
}
@Override
protected void onBeforeClusterItemRendered(final MediaItem mediaItem, final MarkerOptions markerOptions) {
onBeforeClusterOrClusterItemRendered(null, mediaItem, markerOptions);
}
@Override
protected void onBeforeClusterRendered(final Cluster<MediaItem> cluster, final MarkerOptions markerOptions) {
final MediaItem mediaItem = MediaPicker.getBestRated(new ArrayList<>(cluster.getItems()));
onBeforeClusterOrClusterItemRendered(cluster, mediaItem, markerOptions);
}
...
// Re render
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
mClusterManager.onCameraChange(cameraPosition);
final LatLngBounds latLngBounds = mMap.getProjection().getVisibleRegion().latLngBounds;
// Cluster only
Collection<Marker> clusters = mClusterManager.getClusterMarkerCollection().getMarkers();
for(Marker marker : clusters) {
if(isInBounds(marker.getPosition(), latLngBounds))
onBeforeClusterRendered(getCluster(marker), new MarkerOptions());
}
// Cluster item only
Collection<Marker> markers = mClusterManager.getMarkerCollection().getMarkers();
for(Marker marker : markers) {
if(isInBounds(marker.getPosition(), latLngBounds))
onBeforeClusterItemRendered(getClusterItem(marker), new MarkerOptions());
}
}
});
答案 1 :(得分:3)
我有类似的问题。我跟踪用户的初始位置并显示他周围的地图标记。如果用户选择查看外部初始缩放,我会下载其他标记。实施:
map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
setCurrentRadius();
viewCenter = cameraPosition.target;
if (isNewGrounds(viewCenter, viewRadius)) {
downloadExtraPrinters(viewCenter,viewRadius);
}
myClusterManager.onCameraChange(cameraPosition);
}
});
private void setCurrentRadius() {
Projection projection = map.getProjection();
VisibleRegion currentView = projection.getVisibleRegion();
LatLng cameraCenter = map.getCameraPosition().target;
float[] projectionRadius = new float[1];
Location.distanceBetween(currentView.farLeft.latitude, currentView.farLeft.longitude, cameraCenter.latitude, cameraCenter.longitude, projectionRadius);
viewRadius = Math.round((projectionRadius[0] / 1000.0f) + 0.5f);
}
/** Method checks if camera goes outside bounds of previously downloaded area **/
protected boolean isNewGrounds(LatLng center, int radius) {
//Check if it is the first time to update
if (coveredGroundsCenter== null) {
coveredGroundsCenter=center;
coveredGroundsRadius= (int)(radius * EXTRA_RADIUS);
return true;
}else {
float[] centerDistance = new float[1];
Location.distanceBetween(coveredGroundsCenter.latitude, coveredGroundsCenter.longitude, center.latitude, center.longitude, centerDistance);
int criticalDistance = (int) Math.round((centerDistance[0] / 1000.0f) + 0.5f) + radius;
if (coveredGroundsRadius >= criticalDistance) {
return false;
} else {
coveredGroundsCenter = center;
coveredGroundsRadius = (int) (radius * EXTRA_RADIUS);
return true;
}
}
}
EXTRA_RADIUS是一个常量,我用它在可见地图区域外有一个小的边距,因此最小的相机移动不会导致我的地图下载和重新渲染。我选择这个边距是当前半径的50%:
private static final double EXTRA_RADIUS=1.5;
private LatLng coveredGroundsCenter;
private int coveredGroundsRadius;
private LatLng viewCenter;