Search code examples
androidgoogle-mapspicassoinfowindow

picasso image not loading in custom infoWindow why?


I'm trying to layout a custom infoWindow programmatically. I want to load a streetView preview image using Picasso but the image isn't showing up, any idea why?

private View prepareInfoView(Marker marker){
    //prepare InfoView programmatically
    LinearLayout infoView = new LinearLayout(EarthquakeActivity.this);
    LinearLayout.LayoutParams infoViewParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    infoView.setOrientation(LinearLayout.VERTICAL);
    // attach the above layout to the infoView
    infoView.setLayoutParams(infoViewParams);

    //create street view preview @ top
    ImageView streetViewPreviewIV = new ImageView(EarthquakeActivity.this);
    // this scales the image to match parents WIDTH?, but retain image's height??
    LinearLayout.LayoutParams streetViewImageViewParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    streetViewPreviewIV.setLayoutParams(streetViewImageViewParams);

    String imageURL = "https://maps.googleapis.com/maps/api/streetview?size=200x200&location=";
    String markerLongitude = Double.toString(marker.getPosition().longitude);
    String markerLatitude = Double.toString(marker.getPosition().latitude);
    imageURL += markerLatitude + "," + markerLongitude + "&fov=120&heading=0&pitch=0";
    Log.wtf("prepareInfoView", imageURL);

    Picasso.with(this).load(imageURL).into(streetViewPreviewIV);
    infoView.addView(streetViewPreviewIV);

I've tried with and without the api key appending the url.

It did work for a few clicks without the key, but hasn't since, with or without. Is the because it's too slow fetching it so Android gives up and loads the info window without it? Is there a best in class way to do this?

Would another image loading library work better? Google's volley?

Also with

LinearLayout.LayoutParams

I'd like the image to stretch across the width of the info windows, i.e. match_parent, and to scale vertically to maintain original aspect ratio, how do I do this?

This is my answer

In commonsWare new class I add this flag:

@Override
public void onSuccess() {
    Log.i(TAG, "image got, should rebuild window");
    if (marker != null && marker.isInfoWindowShown()) {
        Log.i(TAG, "conditions met, redrawing window");
        marker.setTag(new Boolean("True"));
        marker.showInfoWindow();
    }
}

And in prepareInfoView, I test for the flags absence.

    if (marker.getTag() == null ) {
        Log.i("prepareInfoView", "fetching image");
        Picasso.with(this).load(imageURL).fetch(new MarkerCallback(marker));
    }
    else {
        Log.wtf("prepareInfoView", "building info window");

Party on! :)


Solution

  • Is the because it's too slow fetching it so Android gives up and loads the info window without it?

    Picasso loads asynchronously unless the image is cached. And the way Maps V2 works is that the View you return is converted into a Bitmap, and that is what gets rendered. As a result, you have a race condition between Picasso and Maps V2 (does the image get loaded before the Bitmap gets created?), and so it is indeterminate as to whether or not any given info window will work.

    You can call showInfoWindow() on the Marker after Picasso has loaded the image, so you can populate the ImageView from Picasso's cache. showInfoWindow(), called on a Marker, triggers Maps V2 to regenerate the info window.

    For example, you could change your existing into() call into into(streetViewPreviewIV, new MarkerCallback(marker)), with a MarkerCallback like:

      static class MarkerCallback implements Callback {
        Marker marker=null;
    
        MarkerCallback(Marker marker) {
          this.marker=marker;
        }
    
        @Override
        public void onError() {
          Log.e(getClass().getSimpleName(), "Error loading thumbnail!");
        }
    
        @Override
        public void onSuccess() {
          if (marker != null && marker.isInfoWindowShown()) {
            marker.showInfoWindow();
          }
        }
      }
    

    Would another image loading library work better? Google's volley?

    They will all suffer from the same issue.