Agregar una imagen de url a InfoWindow personalizado google maps v2

Estoy trabajando en una aplicación para Android. El usuario realiza una búsqueda en google maps para restaurantes. En google mapa marcadores de pantalla para todo el restaurante de su vecino. Si toca en un marcador, aparece una InfoWindow personalizada. Mi problema es que no puedo cargar la imagen que devuelve los lugares de Google forma. Im consiguiendo derecho el URL de la imagen pero no puedo demostrarla en la ventana.

InfoWindow

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:background="@color/bg_color" > <ImageView android:id="@+id/place_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false"" /> <TextView android:id="@+id/place_title" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/place_vicinity" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@color/bg_color" > <RatingBar android:id="@+id/place_rating" style="?android:attr/ratingBarStyleSmall" android:numStars="5" android:rating="0" android:isIndicator="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dip" /> <ImageView android:id="@+id/navigate_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:src="@drawable/navigate" /> </LinearLayout> 

En crear tengo esto

 mGoogleMap.setInfoWindowAdapter(new InfoWindowAdapter() { // Use default InfoWindow frame @Override public View getInfoWindow(Marker arg0) { return null; } // Defines the contents of the InfoWindow @Override public View getInfoContents(Marker arg0) { // Getting view from the layout file info_window_layout View v = getLayoutInflater().inflate(R.layout.info_window_layout, null); // Getting the snippet from the marker String snippet = arg0.getSnippet(); // Getting the snippet from the marker String titlestr = arg0.getTitle(); String cutchar1= "%#"; String cutchar2= "%##"; String ratingstr = snippet.substring(0,snippet.indexOf( cutchar1 )); String vicinitystr = snippet.substring(snippet.indexOf( cutchar1 )+2, snippet.indexOf( cutchar2 ) ); String iconurl= snippet.substring(snippet.indexOf( cutchar2 )+3); // Getting reference to the TextView to set latitude TextView title = (TextView) v.findViewById(R.id.place_title); TextView vicinity = (TextView) v.findViewById(R.id.place_vicinity); ImageView image = (ImageView) v.findViewById(R.id.navigate_icon); // Setting the latitude title.setText(titlestr); // declare RatingBar object RatingBar rating=(RatingBar) v.findViewById(R.id.place_rating);// create RatingBar object if( !(ratingstr.equals("null")) ){ rating.setRating(Float.parseFloat(ratingstr)); } vicinity.setText(vicinitystr); final DownloadImageTask download = new DownloadImageTask((ImageView) v.findViewById(R.id.place_icon) ,arg0); download.execute(iconurl); // Returning the view containing InfoWindow contents return v; } 

});

y el código de DownloadImage es:

 private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ImageView bmImage; Marker marker; boolean refresh; public DownloadImageTask(final ImageView bmImage, final Marker marker) { this.bmImage = bmImage; this.marker=marker; this.refresh=false; } public void SetRefresh(boolean refresh ){ this.refresh=true; } /* @Override protected void onPreExecute() { super.onPreExecute(); bmImage.setImageBitmap(null); }*/ @Override protected Bitmap doInBackground(String... urls) { String urldisplay = urls[0]; Bitmap mIcon11 = null; try { InputStream in = new java.net.URL(urldisplay).openStream(); mIcon11 = BitmapFactory.decodeStream(in); } catch (Exception e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return mIcon11; } @Override protected void onPostExecute(Bitmap result) { if(!refresh){ SetRefresh(refresh); bmImage.setImageBitmap(result); marker.showInfoWindow(); } } } 

Finalmente cuando ejecuto el código y toco el marcador el getInfoContents no deja de ejecutar y el icono no aparece.

¿Alguien tiene alguna idea, ¿por qué sucede esto? Por favor, ayúdame …. Gracias en advace !!

He estado construyendo una aplicación similar.

En primer lugar, la razón por la que su InfoWindow no está mostrando la imagen descargada es porque el MapFragment hace que la vista en un Canvas , y luego dibuja eso. Lo que estás viendo en la ventana de información no son las vistas que creaste, sino una "imagen" o "captura de pantalla" de ellas. Básicamente, es necesario llamar a showInfoWindow() nuevo en el objeto Marker , y que volverá a representar el Canvas y su imagen ahora será visible.

Sin embargo, dicho esto, en mi experiencia cargando el Bitmap de Bitmap de la URL y luego la configuración no es la mejor solución. Android no maneja muy bien Bitmap s. Después de cargar varios mapas de bits, una excepción OutOfMemoryError es sólo cuestión de tiempo, dependiendo de la cantidad de memoria del sistema que tenga.

Recomiendo usar la biblioteca de Picasso, que maneja la descarga asíncrona, y el almacenamiento en caché (en la memoria y el disco) y hace que la imagen real cargando sólo una línea ( Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView); ). (más información en http://square.github.io/picasso/ )

La respuesta anterior fue buena, excepto que, como él dijo, ese "retraso" es un poco demasiado mágico para mi gusto. Picasso tiene la opción de usar devoluciones de llamada, y yo recomendaría usar eso (estoy usando eso en mi aplicación).

Primero cree una clase (puede ser interna a su actividad) que implemente la interfaz de Callback de Picasso y reciba un Marker en el constructor (para que pueda showInfoWindow() llamar a showInfoWindow() en ese marcador.

 private class InfoWindowRefresher implements Callback { private Marker markerToRefresh; private InfoWindowRefresher(Marker markerToRefresh) { this.markerToRefresh = markerToRefresh; } @Override public void onSuccess() { markerToRefresh.showInfoWindow(); } @Override public void onError() {} } 

La ventana de información se ve así:

 mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() { @Override public View getInfoWindow(Marker marker) { // inflate view window // set other views content // set image view like this: if (not_first_time_showing_info_window) { Picasso.with(ActivityClass.this).load(restaurantPictureURL).into(imgInfoWindowPicture); } else { // if it's the first time, load the image with the callback set not_first_time_showing_info_window=true; Picasso.with(ActivityClass.this).load(restaurantPictureURL).into(imgInfoWindowPicture,new InfoWindowRefresher(marker)); } return v; } @Override public View getInfoContents(Marker marker) { return null; } }); 

La devolución de llamada es bastante simple, como se puede ver. Sin embargo, al usar este método DEBE tener cuidado de utilizar sólo la devolución de llamada en la primera llamada, y no en las llamadas posteriores (Acabo de poner en que not_first_time_showing_info_window para reflejar la idea … usted tendrá que ver cómo incluir que en la lógica del programa.Si no lo hace, la devolución de llamada de Picasso llamará showInfoWindow() y que volverá a llamar a la devolución de llamada, que se recordará showInfoWindow() … bien, usted puede ver donde se está recursión.

Lo principal es conseguir que la carga de Picasso con la devolución de llamada para ejecutar sólo una vez, y en las llamadas siguientes, sin la devolución de llamada.

He resuelto este problema usando magia negra (aka establecer un retraso). Aproveché el almacenamiento en caché de Picasso y acabo de llamar showInfoWindow unos milisegundos después de que comenzara la carga inicial.

Aquí está mi CustomWindowAdapter.

 class CustomWindowAdapter implements InfoWindowAdapter{ LayoutInflater mInflater; Map<Marker, String> imageStringMapMarker; Context context; public CustomWindowAdapter(LayoutInflater i, Map<Marker, String> imageStringMapMarker2, Context context ){ mInflater = i; imageStringMapMarker = imageStringMapMarker2; } @Override public View getInfoContents(final Marker marker) { View v = mInflater.inflate(R.layout.custom_info_window, null); ImageView ivThumbnail = (ImageView) v.findViewById(R.id.ivThumbnail); String urlImage = imageStringMapMarker.get(marker).toString(); Picasso.with(context).load(Uri.parse(urlImage)).resize(250,250).into(ivThumbnail); return v; } @Override public View getInfoWindow(Marker marker) { // TODO Auto-generated method stub return null; } } 

Y aquí está el método para llamar a la ventana de información en mi actividad principal donde implemento el retraso.

 myMap.setInfoWindowAdapter(new CustomWindowAdapter(this.getLayoutInflater(), imageStringMapMarker, getApplicationContext())); myMap.setOnMarkerClickListener(new OnMarkerClickListener() { @Override public boolean onMarkerClick(final Marker mark) { mark.showInfoWindow(); final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { mark.showInfoWindow(); } }, 200); return true; } }); 

Sea lo que sea que getInfoContents() de getInfoContents() , en ese momento, se convierte en un Bitmap y se utiliza para mostrar los resultados. No mostrará la imagen hasta más tarde, cuando se haya completado la descarga, momento en el que el Bitmap ya está creado y utilizado.

Usted tendrá que descargar la imagen antes de getInfoContents() ha sido llamado.

Hago esto, también haciendo referencia a la respuesta de @Daniel Gray :

 if (userImg.getDrawable() == null) { Picasso.with(ctx).load(UtilitiesApp.urlServer + user.getImgUrl()) .error(R.drawable.logo) .into(userImg, new InfoWindowRefresher(marker)); } else { Picasso.with(ctx).load(UtilitiesApp.urlServer + user.getImgUrl()) .error(R.drawable.logo) .into(userImg); } public class InfoWindowRefresher implements Callback { private Marker markerToRefresh; public InfoWindowRefresher(Marker markerToRefresh) { this.markerToRefresh = markerToRefresh; } @Override public void onSuccess() { markerToRefresh.showInfoWindow(); } @Override public void onError() {} } 
  • Utilidades de mapas de Android Clustering show InfoWindow
  • Cómo agregar contenidoDescrito a InfoWindow o marcador en Android GoogleMaps V2 para TalkBack
  • Android Google Map API V2: Abrir ventana de información personalizada en el lado derecho del marcador
  • Adaptador de ventana de información personalizada con datos personalizados en el mapa v2
  • Diferencia entre getInfoWindow () y getInfoContents () en Googlemaps v2 para Android
  • Botón onclicklistener en infowindow en google map
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.