在Google Maps v2 for Android中刷新制造商(ClusterItems)

11

我正在使用Google Maps Android API实用程序库,并且我正在从互联网上下载一些我想要用作标记的特定图像。 我的做法类似于以下代码片段:

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个回答

5

你只需要将所有这些东西制作成

protected void onClusterItemRendered(T clusterItem, Marker marker) {
    ...
}

onBeforeClusterItemRendered中,您可以在异步回调中设置MarkerOptions图标。此时它可能已经添加到地图上并成为真正的Marker。因此,您的图标将被设置为已经无用的对象。
这就是为什么您需要在onClusterItemRendered中这样做。

0
假设您已经声明了GoogleMap对象: private GoogleMap mMap;
在onResponse()方法中,在应用任何更改之前,请尝试编写以下语句以清除先前的标记: mMap.clear();
现在设置您的新标记。

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,则无需再次加载图像,因为它已经存储在标记对象中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接