0

I am learning how to use Android Studio to make Google Maps applications. I wanted to make a custom info window for my markers that displays a snippet with the information of the place as well as an ImageView with an image of that place.

My photo is coming from a URL and i am using a Thread inside my custom info window class to import that image.

My issue is that for some reason the image does not change from marker to marker and i don't know what's the cause of this.

This is the code of my custom info window.

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.Marker;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;


public class CustomInfoWindow implements GoogleMap.InfoWindowAdapter {
    private static final String TAG = "CustomInfoWindow";
    private final View window;
    private Context context;
    private String photo;
    private ImageView img;
    public CustomInfoWindow(Context context,String photo) {
        this.context = context;
        this.photo = photo;
        window = LayoutInflater.from(context).inflate(R.layout.custom_makrer_info,null);
    }

    private void renderWindow(Marker marker,final View view){
        String title = marker.getTitle();
        TextView tv_Title = (TextView)view.findViewById(R.id.marker_title);

        if (!title.equals("")){
            tv_Title.setText(title);
        }
        String snippet = marker.getSnippet();
        TextView tv_Snippet = (TextView)view.findViewById(R.id.marker_snippet);

        if (!snippet.equals("")){
            tv_Snippet.setText(snippet);
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                img = (ImageView)view.findViewById(R.id.marker_image);
                if (!photo.equals("")){
                    try {
                        URL url = new URL(photo);
                        Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
                        img.setImageBitmap(bmp);

                    }catch (MalformedURLException e){
                        Log.e(TAG, "renderWindow: MalformedURLException thrown: " +e.getMessage() );
                    } catch (IOException e) {
                        Log.e(TAG, "renderWindow: IOException thrown "+ e.getMessage() );
                    }
                }
            }
        }).start();
    }

    @Override
    public View getInfoWindow(Marker marker) {
        renderWindow(marker,window);
        return window;
    }

    @Override
    public View getInfoContents(Marker marker) {
        renderWindow(marker,window);
        return window;
    }
}

and this is how i am adding my markers on the map

private void addNewMarker(POI placeInfo){
        mMap.setInfoWindowAdapter(new CustomInfoWindow(MapsActivity.this,placeInfo.getPhotos()));

        try {
            String snippet = "ID: " + placeInfo.getID() + "\nCategory: "+ placeInfo.getCategory();
            mMarker = mMap.addMarker(new MarkerOptions()
                    .title(placeInfo.getPOI_name())
                    .position(new LatLng(placeInfo.getLatitude(),placeInfo.getLongitude()))
                    .snippet(snippet));
        }catch (NullPointerException e){
            Log.e(TAG, "moveCamera: NullPointerException thrown: " + e.getMessage() );
        }

    }

this method is called for each element POI in a list.

Any help would be highly appreciated Thanks in advance

Sakis
  • 31
  • 12
  • https://stackoverflow.com/a/36335163/115145 – CommonsWare May 28 '18 at 12:45
  • i'd prefer a better explanation of what i am doing wrong, this link is somewhat helpful but i still don't understand why what i have is wrong and also how to use Picasso. I tried to do something similar to what you recommended but i am still having the same issue – Sakis May 28 '18 at 13:35
  • Quoting the answer I linked to: "The info window is basically a bitmap, captured from the views that you populated. As a result, changes to those views — such as Picasso asynchronously updating an `ImageView` — will not update the info window". In your case, you are rolling your own code instead of using a library, but you are still trying to update the `View` after `getInfoWindow()` returns. This will not work, as the `View` is not used after it is converted into a `Bitmap`, so your changes come too late. – CommonsWare May 28 '18 at 13:47
  • Once again, quoting the answer: "One solution that works is to call `showInfoWindow()` on the `Marker` after Picasso has obtained and cached the image." In your case, you would need to do your own caching. So, `getInfoWindow()` pulls the image from the cache and uses it; if the image is not in the cache, it forks the thread to populate the cache. That thread calls `showInfoWindow()` when the cache is ready, so you get a fresh `getInfoWindow()` call and can use the image. – CommonsWare May 28 '18 at 13:49
  • Sorry I was quite a bit frustrated because i have been trying to fix this issue almost all day, after taking a short break to calm down i think i understood better the logic behind all this. I think managed to fix this issue. Thank you very much – Sakis May 28 '18 at 16:08

0 Answers0