Google Maps v2 for Android中的刷新制作者(ClusterItems)

时间:2014-03-24 13:16:19

标签: android google-maps google-maps-markers google-maps-android-api-2 markerclusterer

我正在使用Google Maps Android API Utility Library,我正在从互联网上下载我想用作标记的某些图片。 我这样做的方式如下面的代码段所示:

class MarkerItemClusterRenderer extends DefaultClusterRenderer<MarkerItem> {
...
    @Override
        protected void onBeforeClusterItemRendered(MarkerItem item,
                final MarkerOptions markerOptions) {
            super.onBeforeClusterItemRendered(item, markerOptions);
            mImageLoader.get(item.getImageUrl(), new ImageListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.i("XXX", error.toString());
                }

                @Override
                public void onResponse(ImageContainer response, boolean isImmediate) {
                    if (response != null && response.getBitmap() != null) {
                        mImageIcon.setImageBitmap(response.getBitmap());
                        Bitmap icon = mIconGenerator.makeIcon();
                        Bitmap bhalfsize = Bitmap.createScaledBitmap(icon, 150,
                                150, false);
                        markerOptions.icon(BitmapDescriptorFactory
                                .fromBitmap(bhalfsize));
                    }
                }
            });
        }

问题是,当下载图像时,地图(以及标记)不会刷新,因此大多数时候(但并非总是如此)我仍然会看到红色的默认标记。

我试图做mImageIcon.invalidate(); mImageIcon.requestLayout();,但仍然没有运气。

反正有没有实现这个目标? 非常感谢。

3 个答案:

答案 0 :(得分:3)

你只需要在

中制作所有这些东西
protected void onClusterItemRendered(T clusterItem, Marker marker) {
    ...
}

onBeforeClusterItemRendered中,您在异步回调中的MarkerOptions上设置了图标。此时,它可以添加到地图并变为真实Marker。所以你的图标将被设置为已经无用的对象。

这就是你需要在onClusterItemRendered

中完成的原因

答案 1 :(得分:0)

假设您将GoogleMap对象声明为:         私人GoogleMap mMap;

在对标记应用任何更改之前的onResponse()方法中,尝试编写以下语句以清除以前的标记:         mMap.clear();

现在设置新标记。

答案 2 :(得分:0)

我可能会有点迟,但我把它写下来,这对于寻找像我这样的解决方案的人来说非常有用。 基本上你要做的就是刷新标记而不是ClusterItem,但我使用自己的ClusterItem实现来存储一些重要的数据。 所以onBeforeClusterItemRendered中的代码就像这样:

LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; //take visible region on map
if(bounds.contains(item.getPosition()) && !item.hasImage()) { //if item is not inside that region or it has an image already don't load his image
    mImageLoader.get(item.getImageUrl(), new ImageListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("XXX", error.toString());
            }

            @Override
            public void onResponse(ImageContainer response, boolean isImmediate) {
                if (response != null && response.getBitmap() != null) {
                    mImageIcon.setImageBitmap(response.getBitmap());
                    Bitmap icon = mIconGenerator.makeIcon();
                    Bitmap bhalfsize = Bitmap.createScaledBitmap(icon, 150,
                            150, false);

                    //Set has image flag
                    item.setHasImage(true);

                    //Find the right marker
                    MarkerManager.Collection markerCollection = mClusterManager.getMarkerCollection();
                    Collection<Marker> markers = markerCollection.getMarkers();
                    for (Marker m : markers) {
                        if (id.equals(m.getTitle())) {
                            //set the icon
                            m.setIcon(BitmapDescriptorFactory.fromBitmap(image));
                            break;
                        }
                    }
                }
            }
    });
}

你的MyItem类必须有一些对记住我们的东西有用的参数:

public class MyItem implements ClusterItem {

private String itemId;
private LatLng mPosition;
private WMWall wall;
private boolean hasImage = false;

public MyItem(double latitude, double longitude) {
    mPosition = new LatLng(latitude, longitude);
}

@Override
public LatLng getPosition() {
    return mPosition;
}

public WMWall getWall() {
    return wall;
}

public void setWall(WMWall wall) {
    this.wall = wall;
}

public String getItemId() {
    return itemId;
}

public void setItemId(String itemId) {
    this.itemId = itemId;
}

public boolean hasImage() {
    return hasImage;
}

public void setHasImage(boolean hasImage) {
    this.hasImage = hasImage;
}
}

仅加载包含在边界中的标记图像非常重要,否则您将遇到OOM。 如果hasImage()方法返回true,我们不需要再次加载图像,因为它已经存储在标记对象中。