Создатели обновлений (ClusterItems) в Google Maps v2 для Android

Я использую библиотеку утилит 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)


Вам просто нужно сделать все это в

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

В onBeforeClusterItemRendered вы устанавливаете значок на MarkerOptions в асинхронном обратном вызове. В это время его можно было добавить на карту и стать настоящим Marker. Таким образом, ваша иконка будет установлена ​​на уже бесполезный объект.

Вот почему вам нужно сделать это в onClusterItemRendered

person Stas Parshin    schedule 01.12.2015

Допустим, у вас есть объект GoogleMap, объявленный как: private GoogleMap mMap;

В методе onResponse() перед применением каких-либо изменений к маркеру попробуйте написать следующий оператор для очистки предыдущих маркеров: mMap.clear();

Теперь установите новый маркер.

person Community    schedule 02.06.2014

Я могу немного опоздать, но я запишу это, чтобы оно могло быть полезно для тех, кто ищет решение, как я. По сути, вам нужно обновить маркер, а не 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, нам не нужно снова загружать изображение, так как оно уже сохранено в объекте маркера.

person MineConsulting SRL    schedule 08.08.2015