【问题标题】:picasso image not loading in custom infoWindow why?毕加索图像没有加载到自定义信息窗口中,为什么?
【发布时间】:2017-01-25 21:07:35
【问题描述】:

我正在尝试以编程方式布局自定义 infoWindow。我想使用 Picasso 加载街景预览图像,但图像没有显示,知道为什么吗?

private View prepareInfoView(Marker marker){
    //prepare InfoView programmatically
    LinearLayout infoView = new LinearLayout(EarthquakeActivity.this);
    LinearLayout.LayoutParams infoViewParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    infoView.setOrientation(LinearLayout.VERTICAL);
    // attach the above layout to the infoView
    infoView.setLayoutParams(infoViewParams);

    //create street view preview @ top
    ImageView streetViewPreviewIV = new ImageView(EarthquakeActivity.this);
    // this scales the image to match parents WIDTH?, but retain image's height??
    LinearLayout.LayoutParams streetViewImageViewParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    streetViewPreviewIV.setLayoutParams(streetViewImageViewParams);

    String imageURL = "https://maps.googleapis.com/maps/api/streetview?size=200x200&location=";
    String markerLongitude = Double.toString(marker.getPosition().longitude);
    String markerLatitude = Double.toString(marker.getPosition().latitude);
    imageURL += markerLatitude + "," + markerLongitude + "&fov=120&heading=0&pitch=0";
    Log.wtf("prepareInfoView", imageURL);

    Picasso.with(this).load(imageURL).into(streetViewPreviewIV);
    infoView.addView(streetViewPreviewIV);

我尝试过使用和不使用附加 url 的 api 键。

它确实可以在没有密钥的情况下点击几下,但从那以后不管有没有都没有。是因为它获取它的速度太慢所以Android放弃并在没有它的情况下加载信息窗口?是否有同类最佳的方法来做到这一点?

另一个图像加载库会更好吗?谷歌的凌空?

还有

LinearLayout.LayoutParams

我希望图像跨越信息窗口的宽度,即 match_parent,并垂直缩放以保持原始纵横比,我该怎么做?

这是我的答案

在 commonsWare 新类中我添加了这个标志:

@Override
public void onSuccess() {
    Log.i(TAG, "image got, should rebuild window");
    if (marker != null && marker.isInfoWindowShown()) {
        Log.i(TAG, "conditions met, redrawing window");
        marker.setTag(new Boolean("True"));
        marker.showInfoWindow();
    }
}

在 prepareInfoView 中,我测试标志是否缺失。

    if (marker.getTag() == null ) {
        Log.i("prepareInfoView", "fetching image");
        Picasso.with(this).load(imageURL).fetch(new MarkerCallback(marker));
    }
    else {
        Log.wtf("prepareInfoView", "building info window");

开派对! :)

【问题讨论】:

    标签: android google-maps picasso infowindow


    【解决方案1】:

    如果您使用公认的答案来解决问题,但仍然无法解决问题, 您可能正在使用 .fit() 。 换句话说,您应该从 Picasso 代码中删除 .fit() 。 我花了几个小时才意识到这一点。

    【讨论】:

      【解决方案2】:

      我也为此苦苦挣扎,这是一个受公认答案启发的滑翔解决方案。 如果不将图片调整为适当的大小,此解决方案对我不起作用。有了override()(和centerCrop),它就成功了。

      跟踪显示的最新图片

      private String previousImageUrl = null;
      

      并用它来查看是否需要刷新当前图像

      googleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
          @Override
          public View getInfoWindow(Marker marker) {
              return null;
          }
      
          @Override
          public View getInfoContents(final Marker marker) {
              View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_map_info_window, null);
              MyObject myObject = (MyObject) marker.getTag();
              final String url = myObject.getImageUrl();
              final ImageView imageView = (ImageView) view.findViewById(R.id.image_view);
              GlideApp.with(getContext()).load(url)
                      .override(imageWidth, imageHeight) // made the difference
                      .centerCrop()
                      .into(new SimpleTarget<Drawable>() {
                          @Override
                          public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
                              imageView.setImageDrawable(resource);
                              if (!TextUtils.equals(url, previousImageUrl)) {
                                  previousImageUrl = url;
                                  marker.showInfoWindow();
                              }
                          }
                      });
              return view;
          }
      });
      

      【讨论】:

        【解决方案3】:

        我只知道, Picasso 异步加载图像,因此当标记通过内部调用方法 getInfoContentsgetInfoWindow 方法单击后显示它的信息窗口时, 此时,如果 Picasso 尚未下载或缓存图像,则它不会显示在 infoWindow 上。 Picasso 在下载时尝试将图像加载到 infoWindow 的 imageview 中,但是根据 Google maps V2,infoWindows 一旦加载,就无法操作,因此图像不显示在 UI 上更新。 但是 infowindow 视图实际上已更新但无法显示限制,因此如果您只是隐藏并显示 infowindow ,它有点刷新,并且图像显示在更新后的 infoWindow 。您可以通过以下方式执行此操作,

        你需要保留marker的引用,你可以把它作为Activity/Fragment的成员变量。

         Picasso.with(context)
                                .load(marker.getSnippet())
                                .placeholder(R.drawable.ic_placeholder)
                                .into(imageView, new Callback() {
                                @Override
                                public void onSuccess() {
        
                                    if (currentClickedMarker != null && currentClickedMarker.isInfoWindowShown()) {
        //toggle the marker's infoWindow
                                        currentClickedMarker.hideInfoWindow();
        
                                        currentClickedMarker.showInfoWindow();
                                    }
                                }
        
                                @Override
                                public void onError() {
        
                                }
                            });
        

        【讨论】:

          【解决方案4】:

          对我有用的是:

          public class MarkerCallback implements Callback {
              Marker marker=null;
              String URL;
              ImageView userPhoto;
          
          
              MarkerCallback(Marker marker, String URL, ImageView userPhoto) {
                  this.marker=marker;
                  this.URL = URL;
                  this.userPhoto = userPhoto;
              }
          
              @Override
              public void onError() {
                  //Log.e(getClass().getSimpleName(), "Error loading thumbnail!");
              }
          
              @Override
              public void onSuccess() {
                  if (marker != null && marker.isInfoWindowShown()) {
                      marker.hideInfoWindow();
          
                      Picasso.with(getActivity())
                              .load(URL)                        
                              .into(userPhoto);
          
                      marker.showInfoWindow();
                  }
              }
          }
          

          【讨论】:

          • 这有点工作。导致信息窗口闪烁:(
          【解决方案5】:

          是不是因为获取它太慢所以 Android 放弃并在没有它的情况下加载信息窗口?

          除非图像被缓存,否则毕加索会异步加载。 Maps V2 的工作方式是将您返回的View 转换为Bitmap,这就是被渲染的内容。因此,Picasso 和 Maps V2 之间存在竞争条件(图像是否在创建 Bitmap 之前加载?),因此不确定任何给定的信息窗口是否可以工作。

          Picasso 加载图像后,您可以在 Marker 上调用 showInfoWindow(),以便从 Picasso 的缓存中填充 ImageViewshowInfoWindow(),在 Marker 上调用,触发 Maps V2 重新生成信息窗口。

          例如,您可以将现有的 into() 调用更改为 into(streetViewPreviewIV, new MarkerCallback(marker)),并使用 MarkerCallback 之类的:

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

          另一个图像加载库会更好吗?谷歌的凌空?

          他们都会遇到同样的问题。

          【讨论】:

          • 感谢 CommonsWare,非常有启发性。我喜欢您的解决方案,并实现了它,但它触发了无限循环!它不断地一遍又一遍地获取图像。现在想这个太累了,所以感谢您的关注:)
          • @TonyStark:啊,是的,我的整个适配器中可能有一些位可以避免这种情况。这是整个示例项目:github.com/commonsguy/cw-omnibus/tree/master/MapsV2/ImagePopups
          • 感谢 CommonsWare,我实际上让您的原始代码正常工作,只是使用了 marker.setTag,来传输一个布尔标志。我会用答案更新问题,并感谢您。有一天我想成为 commonsWare 大师 :)
          • 如果这对您不起作用,请确保您没有在 Picasso 中使用.fit()centerCrop 或其他类似功能。我现在正在想办法解决。
          猜你喜欢
          • 2018-11-22
          • 2014-09-26
          • 2017-07-14
          • 1970-01-01
          • 2020-05-02
          • 1970-01-01
          • 2016-07-25
          • 2021-08-09
          相关资源
          最近更新 更多