简体   繁体   English

如何使用毕加索在Google Maps的infoWindow中获取图像-Android

[英]How to get image in infoWindow on Google Maps with picasso - Android

I have created an app that implements a MapsView. 我创建了一个实现MapsView的应用程序。 And when i click the marker, it will show me the info window where the data is retrieved from the database by using picasso. 当我单击标记时,它将向我显示信息窗口,其中使用毕加索从数据库中检索数据。 It works fine, but the problem is that the image in the info window not shows me the image that i needed, it still shows me the placeholder image. 它工作正常,但问题是信息窗口中的图像未显示我所需的图像,但仍显示了占位符图像。 But when i click the map and click again to the marker, it will shows me the image that i needed. 但是,当我单击地图并再次单击标记时,它将显示我所需的图像。 But if i'm not clicking on the map (still clicking the marker), it still always shows me the placeholder marker. 但是,如果我没有在地图上单击(仍在单击标记),它仍然始终向我显示占位符标记。 How do I display the image that i needed (the placeholder image will replace with the image that i needed) with a time? 如何显示我需要的图像(占位符图像将替换为我需要的图像)?

Here's my code 这是我的代码

public void plotMarkers(ArrayList<MyMarker> markers) {
    if(markers.size() > 0) {
        for (MyMarker myMarker : markers)
        {
            dest = new LatLng(myMarker.getmLatitude(), myMarker.getmLongitude());
            markerOption = new MarkerOptions().position(dest);
            location_marker = mMap.addMarker(markerOption);
            Target target = new PicassoMarker(location_marker);
            targets.add(target);

            ImageView image = new ImageView(this);
            image.setImageResource(R.mipmap.marker);
            int width = image.getDrawable().getIntrinsicWidth();
            int height = image.getDrawable().getIntrinsicHeight();

            Picasso.with(MapsActivity.this).load(myMarker.getmIcon()).resize(width, height).onlyScaleDown().into(target);
            mMarkersHashMap.put(location_marker, myMarker);

            i = getIntent();
            if(i.getBooleanExtra("maps", true)) {
                location_marker.setTitle(i.getStringExtra("nama"));
                mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(dest, 16));
            }
            else {
                mMap.setInfoWindowAdapter(new MarkerInfoWindowAdapter());
            }
        }
    }
}

public class MarkerInfoWindowAdapter implements GoogleMap.InfoWindowAdapter
{
    @Override
    public View getInfoWindow(Marker marker) {
        return null;
    }

    @Override
    public View getInfoContents(Marker marker) {
        View v  = getLayoutInflater().inflate(R.layout.info_windowlayout, null);

        MyMarker myMarker = mMarkersHashMap.get(marker);

        TextView markerLabel = (TextView) v.findViewById(R.id.marker_label);
        markerLabel.setText(myMarker.getmLabel());

        ImageView foto = (ImageView) v.findViewById(R.id.foto);
        Picasso.with(getApplicationContext()).load(myMarker.getmImage()).placeholder(R.layout.progress).error(R.mipmap.error).into(foto);

        TextView anotherLabel = (TextView) v.findViewById(R.id.another_label);
        anotherLabel.setText("Baca selengkapnya...");

        return v;
    }
}

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. 结果,对这些视图的更改(例如Picasso异步更新ImageView )将不会更新信息窗口。

One solution that works is to call showInfoWindow() on the Marker after Picasso has obtained and cached the image. 一种有效的解决方案是在毕加索获取并缓存图像后,在Marker上调用showInfoWindow() For example, this sample app uses Picasso to populate info windows, and uses a Picasso Callback to call showInfoWindow() : 例如, 此示例应用程序使用Picasso填充信息窗口,并使用Picasso Callback调用showInfoWindow()

/***
  Copyright (c) 2013-2014 CommonsWare, LLC
  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  From _The Busy Coder's Guide to Android Development_
    https://commonsware.com/Android
 */

package com.commonsware.android.mapsv2.imagepopups;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.HashMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.model.Marker;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

class PopupAdapter implements InfoWindowAdapter {
  private View popup=null;
  private LayoutInflater inflater=null;
  private HashMap<String, Uri> images=null;
  private Context ctxt=null;
  private int iconWidth=-1;
  private int iconHeight=-1;
  private Marker lastMarker=null;

  PopupAdapter(Context ctxt, LayoutInflater inflater,
               HashMap<String, Uri> images) {
    this.ctxt=ctxt;
    this.inflater=inflater;
    this.images=images;

    iconWidth=
        ctxt.getResources().getDimensionPixelSize(R.dimen.icon_width);
    iconHeight=
        ctxt.getResources().getDimensionPixelSize(R.dimen.icon_height);
  }

  @Override
  public View getInfoWindow(Marker marker) {
    return(null);
  }

  @SuppressLint("InflateParams")
  @Override
  public View getInfoContents(Marker marker) {
    if (popup == null) {
      popup=inflater.inflate(R.layout.popup, null);
    }

    if (lastMarker == null
        || !lastMarker.getId().equals(marker.getId())) {
      lastMarker=marker;

      TextView tv=(TextView)popup.findViewById(R.id.title);

      tv.setText(marker.getTitle());
      tv=(TextView)popup.findViewById(R.id.snippet);
      tv.setText(marker.getSnippet());

      Uri image=images.get(marker.getId());
      ImageView icon=(ImageView)popup.findViewById(R.id.icon);

      if (image == null) {
        icon.setVisibility(View.GONE);
      }
      else {
        Picasso.with(ctxt).load(image).resize(iconWidth, iconHeight)
               .centerCrop().noFade()
               .placeholder(R.drawable.placeholder)
               .into(icon, new MarkerCallback(marker));
      }
    }

    return(popup);
  }

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

Basically, if when Picasso gets the image, the info window is still open for the associated Marker , I call showInfoWindow() . 基本上,如果毕加索获取图像时,仍为关联的Marker打开信息窗口,则调用showInfoWindow() The visual effect resembles normal Picasso behavior: a placeholder, followed by the real image replacing the placeholder. 视觉效果类似于正常的毕加索行为:一个占位符,然后用实际图像替换该占位符。

kotlin version 科特林版本

   Picasso.get()
            .load(it.avatar)
            .placeholder(R.drawable.ic_person_black_24dp)
            .error(R.drawable.ic_person_black_24dp)
            .into(avatarView, object : Callback {
                override fun onSuccess() {
                    if (marker != null && marker.isInfoWindowShown) {
                        marker.hideInfoWindow()
                        marker.showInfoWindow()
                    }
                }

                override fun onError(e: Exception?) {
                    Timber.e("Error loading avatar to info window!")
                }
            })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM