1

У меня есть одна проблема.Пользовательский значок маркера с изображения URL GoogleMap API V2

Моя цель - загрузить пользовательское изображение компании и показать ее вместо значка маркера по умолчанию.

Но я столкнулся с проблемой.

Значки отображаются только в том случае, если я снова закрываю и открываю действие.

Вот мой код для добавления маркеров на карту.

private void addMarkerToTheMap(GoogleMapInfoBundle infoBundle) { 
     if (infoBundle.placeMarker) { 
      LatLng latLng = new LatLng(infoBundle.company.getLatitude(), infoBundle.firm.getLongitude()); 
      MarkerOptions markerOptions = new MarkerOptions() 
        .title(infoBundle.company.getName()) 
        .snippet(infoBundle.company.getAddress()) 
        .position(latLng); 
      Marker marker = mGoogleMap.addMarker(markerOptions); 
      try { 
       Picasso.with(this).load(NetworkUtils.getUrlOfScaledImage(infoBundle.company.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE)).into(new PicassoMarker(marker)); 
      } catch (IllegalArgumentException ignore) { 
       // Do nothing 
      } 
     } 

И PicassoMarker

public class PicassoMarker implements Target { 
    Marker mMarker; 

    public PicassoMarker(Marker marker) { 
     mMarker = marker; 
    } 

    @Override 
    public int hashCode() { 
     return mMarker.hashCode(); 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (o instanceof PicassoMarker) { 
      Marker marker = ((PicassoMarker) o).mMarker; 
      return mMarker.equals(marker); 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 
     mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap)); 
    } 

    @Override 
    public void onBitmapFailed(Drawable errorDrawable) { 
    } 

    @Override 
    public void onPrepareLoad(Drawable placeHolderDrawable) { 

    } 
} 

В этом случае отображается значок по умолчанию enter image description here.

Я попытался сделать это по-другому, как этот

MarkerOptions markerOptions = new MarkerOptions() 
         .title(infoBundle.company.getName()) 
         .snippet(infoBundle.company.getAddress()) 
         .position(latLng); 
    try { 
       Picasso.with(this).load(NetworkUtils.getUrlOfScaledImage(infoBundle.company.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE)).into(new PicassoMarker(mGoogleMap, markerOptions)); 
      } catch (IllegalArgumentException ignore) { 
       // Do nothing 
      } 

И добавить маркер на карте в обратный вызов после того, как изображение было загружено.

@Override 
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 
     mMarkerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap)); 
     mGoogleMap.addMarker(mMarkerOptions); 
    } 

В этом случае маркер не отображается.

Но в обоих случаях, если я закрою Activity и откройте его, все будет отображаться правильно с иконками.

Я понятия не имею, что может вызвать такую ​​проблему. Кажется GoogleMap кэширует изображение иконки или что-то еще.

У меня есть небольшой опыт работы с GoogleMaps API, может быть, я чего-то не хватает.

Надеюсь, кто-то может помочь.

Спасибо.

ответ

1

Проблема была не в GoogleMap или SupportMapFragment это было в Picasso, не совсем в Picasso, но в моем потоке.

Вещь, которую Вы должны всегда помнить, используя пользовательские Target классов является то, что внутренне Picasso использует WeakReference для хранения Target объектов, так что если вы просто создать новый Target непосредственно внутри Picasso называют это будет уничтожен сборщиком мусора.

Picasso класс Callback, поэтому вы можете создать анонимный класс и что класс будет содержать ссылку.

Но одна вещь, которая у меня отсутствует Callback класс, который дает Bitmap в ответе как Target (но цели в основном используются пользовательскими видами).

Так что я нашел такое решение, это уродливо, но вот оно.

Я создал специальный список для хранения целевых объектов, а не для мусора.

Marker marker = mGoogleMap.addMarker(markerOptions); 
      mMarkerCompanyMap.put(marker, infoBundle.firm); 
      try { 
       PicassoMarkerTarget markerTarget = new PicassoMarkerTarget(marker, mImageLoadingCallback); 
       mPicassoMarkerTargetList.add(markerTarget); 
       Picasso.with(this) 
         .load(NetworkUtils.getUrlOfScaledImage(infoBundle.firm.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE)) 
         .into(markerTarget); 
      } catch (IllegalArgumentException ignore) { 
       // Do nothing 
      } 

Я передаю mImageLoadingCallback за то, что обратный вызов назад к деятельности от Target
И это выглядит.

private Callback mImageLoadingCallback = new Callback() { 
     @Override 
     public void onSuccess() { 
      Logger.logError("IMAGE LOADED IN CALLBACK " + mPendingImagesCount); 
      if (mPendingImagesCount <= 0) { 
       mPicassoMarkerTargetList.clear(); 
      } else { 
       mPendingImagesCount--; 
      } 
     } 

     @Override 
     public void onError() { 
      // You may start laughing, but just for the sake of not duplicating code 
      onSuccess(); 
     } 
    }; 

Этот обратный вызов может использоваться для других целей, но теперь только для чистого массива.

И конечно PicassoMarkerTarget

@Override 
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 
     mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap)); 
     mDownloadListenerCallback.onSuccess(); 
     Logger.logError("IMAGE LOADED IN PICASSO MARKER TARGET"); 
    } 

Это некрасиво решение, но, возможно, этот обратный вызов может быть полезным в будущем.

Пожалуйста, если у вас есть идея, как лучше сделать решение - пожалуйста, поделитесь им. Спасибо.