Picasso image loading issue in GoogleMap.InfoWindowAdapter

前端 未结 2 2266
情歌与酒
情歌与酒 2020-12-15 10:25

I am using Google Maps Api and want to show an image inside InfoWindow when clicking of a Marker. I implemented it but there is a problem about Picasso. When I click a marke

2条回答
  •  渐次进展
    2020-12-15 10:37

    I solved it. Actually, this post is the answer. But I want to explain how to do it and give more details to solve this problem in my situation.

    When showing an InfoWindow, it is captured of the layout. It means that InfoWindows are not dynamic, they are just a picture, a snapshot. That's why, we have to refresh the InfoWindow after image loaded successfully. We can use Picasso's Callback to do it.

    I changed my codes like below:

    My new InfoWindowAdapter Class:

    public class MapInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
        private final Hashtable markerSet;
        private Context context;
        private View myContentsView;
    
        public MapInfoWindowAdapter(Context context, Hashtable markerSet) {
            this.context = context;
            this.markerSet = markerSet;
        }
    
        @Override
        public View getInfoWindow(Marker marker) {
            return null;
        }
    
        @Override
        public View getInfoContents(Marker marker) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            myContentsView = inflater.inflate(R.layout.map_info_content, null);
            ImageView imageView = (ImageView) myContentsView.findViewById(R.id.imgView_map_info_content);
            boolean isImageLoaded = markerSet.get(marker.getId());
            if (isImageLoaded) {
                Picasso.with(context)
                        .load(marker.getSnippet())
                        .placeholder(R.drawable.ic_placeholder)
                        .into(imageView);
            } else {
                isImageLoaded = true;
                markerSet.put(marker.getId(), isImageLoaded);
                Picasso.with(context)
                        .load(marker.getSnippet())
                        .placeholder(R.drawable.ic_placeholder)
                        .into(imageView, new InfoWindowRefresher(marker));
            }
    
            return myContentsView;
        }
    }
    

    I passed to it a markers set, it holds marker ids and a boolean to determine image for that marker is loaded or not. I am checking this to select which Picasso code should run. If I don't do this, it will be recursion.

    InfoWindowRefresher:

    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() {}
    }
    

    Setting markers (using snippet to pass image url):

    Hashtable markerSet = new Hashtable<>();
    for (MediaFeedData item : mItemList) {
        LatLng position = new LatLng(item.getLocation().getLatitude(),
                item.getLocation().getLongitude());
        MarkerOptions markerOptions = new MarkerOptions()
                .snippet(item.getImages().getLowResolution().getImageUrl())
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_point))
                .position(position);
        Marker marker = mMap.addMarker(markerOptions);
        markerSet.put(marker.getId(), false);
    }
    
    mMap.setInfoWindowAdapter(new MapInfoWindowAdapter(this, markerSet));
    

提交回复
热议问题