I am working on an application using a Google Map and the Google Places API, let's say I populate the map with different Markers and that I keep track of those Markers inside a
Map<Marker, Place> places = new HashMap<Marker, Place>();
Here is my Place's class :
public class Place {
String placeId;
String name;
public Place(String placeId, String name) {
this.placeId = placeId;
this.name = name;
}
}
I would like to be able to dynamically fill an InfoWindow with data fetched based on the placeId argument, here is what I do inside the InfoWindowAdapter :
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker marker) {
return null;
}
@Override
public View getInfoContents(Marker marker) {
View v = getLayoutInflater().inflate(R.layout.info_window_layout, null);
TextView placeName = (TextView)v.findViewById(R.id.info_window_place_name);
Place place = places.get(marker);
if (place != null) {
placeName.setText(place.name);
String photoUrl = "http://www.plopcontenido.com/wp/wp-content/themes/PlopTheme/img/logo.png";
new DownloadPlacePhoto(v, marker, placeName.toString()).execute(photoUrl);
}
return v;
}
});
private class DownloadPlacePhoto extends AsyncTask<String, Void, Bitmap> {
View v;
Marker marker;
String placeName;
public DownloadPlacePhoto(View v, Marker marker, String placeName) {
this.v = v;
this.marker = marker;
this.placeName = placeName;
}
@Override
protected Bitmap doInBackground(String... urls) {
Bitmap download;
try {
InputStream in = new URL(urls[0]).openStream();
download = BitmapFactory.decodeStream(in);
return download;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap download) {
if (download != null) {
ImageView placeImage = (ImageView)v.findViewById(R.id.info_window_place_photo);
placeImage.setImageBitmap(download);
placeImage.setContentDescription(this.placeName);
placeImage.setVisibility(View.VISIBLE);
if (this.marker.isInfoWindowShown()) {
this.marker.hideInfoWindow();
this.marker.showInfoWindow();
}
}
}
}
The thing is the InfoWindow is a "snapshot" and not a live representation (and I totally understand why) is that the associated Asynctask will run inside another thread so the snapshot will already be taken without my fetched data.
I heard people talking about Observer Pattern and other talking about "you need to get your data stored before you enter the getInfoWindow function, but due to Google Places limitations I can't afford to perform two more requests (one for the picture, and the other one for more data about a specific place) for each Marker.
Any idea about how I could perform this ?