使用Googles android-maps-utils

时间:2015-10-02 14:17:56

标签: java android google-maps google-maps-android-api-2 android-maps-utils

我使用android-maps-utils中的群集在Android上的Google地图上聚类标记。我希望在地图处于最大缩放级别时禁用聚类(即,如果地图处于最大缩放级别,则始终渲染单个ClusterItems,否则群集正常)。

我可以通过在扩展DefaultClusterRenderer的自定义类中的shouldRenderAsCluster()中进行缩放级别测试来使其工作。但是我的解决方案落后于实际缩放级别一步。例如,如果地图的最大缩放是21级,并且用户从级别20放大到级别21,则登记的应该是当前的缩放级别为20的当前缩放级别。如果用户然后缩小到级别20,则检查将获得级别21. ClusterItems被渲染为我想要的单个项目,但是一个缩放操作太晚了。

我得到了"当前缩放" (默认情况下显然不是当前)来自DefaultClusterRenderer中设置的变量mZoom。

这是代码:

public class UserClusterRenderer extends PosMapDefaultClusterRenderer<UserClusterItem> {

    // ...

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        return mZoom < mMap.getMaxZoomLevel() && cluster.getSize() > 1;
    }
}

变量mZoom和mMap在DefaultClusterRenderer中设置。因为他们有私人访问权限,所以我制作了一份名为PosMapDefaultClusterRenderer的DefaultClusterRenderer副本。唯一的区别是mZoom和mMap被声明为受保护,因此可以在UserClusterRenderer中访问它们。

为什么mZoom落后于一个缩放动作?有没有办法获得正在渲染聚类的真实缩放级别?

使用cameraPosition中的cameraUpdate调用animateCamera完成缩放。

这也是我对StackOverflow的第一个问题,所以欢迎任何关于标签,格式等的输入。

编辑:Vai回答后的工作代码:

public class UserClusterRenderer extends DefaultClusterRenderer<UserClusterItem> {

    GoogleMap mMapCopy; // Store a ref to the map here from constructor

    // ...

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        float currentZoom = mMapCopy.getCameraPosition().zoom;
        float currentMaxZoom = mMapCopy.getMaxZoomLevel();
        return currentZoom < currentMaxZoom && cluster.getSize() > 1;
    }
}

3 个答案:

答案 0 :(得分:0)

您不需要对整个班级进行复制以获得mZoom。您可以使用以下方式获取当前缩放(我希望不会滞后):

mMap.getCameraPosition().zoom

shouldRenderAsCluster()的方法看起来是正确的。如果这不起作用,请告诉我,我们会检查一下。欢迎来到SO。

答案 1 :(得分:0)

感谢Breeno向我指出正确的方向。我建议将监听器设置为onCameraIdleListener,因为onCameraMoved被称为sooooo。我已经在地图上使用过onCameraIdle函数,所以我做了类似的事情,并使用Breenos答案更新了渲染器中的当前缩放级别,只是用onCameraIdle切换了onCameraMoved。

private ClusterManager<ClusterItems> mClusterManager;
private ClusterRenderer mRenderer;
private GoogleMap mMap;

@Override
public void onMapReady(GoogleMap googleMap) {
    Log.v("------Map Ready--","-----yuppers");
    mMap = googleMap;
    mMap.setOnCameraIdleListener(this);
    mClusterManager = new ClusterManager<>(this, mMap);
    mRenderer = new ClusterRenderer(getContext(), mMap, mMap.getCameraPosition().zoom);
    mClusterManager.setRenderer(mRenderer);
//        mMap.setOnCameraMoveListener(mRenderer);
//        mMap.setOnCameraIdleListener(mClusterManager);
    mMap.setOnMarkerClickListener(mClusterManager);
    mMap.setOnInfoWindowClickListener(mClusterManager);
    mClusterManager.setOnClusterClickListener(this);
    mClusterManager.setOnClusterInfoWindowClickListener(this);
    mClusterManager.setOnClusterItemClickListener(this);
    mClusterManager.setOnClusterItemInfoWindowClickListener(this); 

}   
@Override
public void onCameraIdle() {
    mClusterManager.onCameraIdle();
    mRenderer.onCameraIdle();
}

答案 2 :(得分:0)

尝试一下:

@Override
protected boolean shouldRenderAsCluster(Cluster cluster) {
    Float zoom = null;
    try {
        this.getClass().getSuperclass().getSuperclass().getDeclaredField("mZoom").setAccessible(true);
        Field field = this.getClass().getSuperclass().getSuperclass().getDeclaredField("mZoom");
        field.setAccessible(true);
        zoom = (Float) field.get(this);
        } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        return cluster.getSize() >= MINIMUM_NUMBER_OF_MARKERS_IN_CLUSTER;
    }
    return cluster.getSize() >= MINIMUM_NUMBER_OF_MARKERS_IN_CLUSTER && (zoom != null ? zoom < MAX_CLUSTERING_ZOOM_LEVEL : true);
}

通过反射解决方案