【问题标题】:infoWindow's image not showing on first click, but it works on second clickinfoWindow 的图像在第一次单击时未显示,但在第二次单击时有效
【发布时间】:2015-07-23 02:20:16
【问题描述】:

我的 android 使用 Google map android API,InfoWindow 的图像在第一次点击时不显示,但在第二次点击时可以工作

我使用

自定义 infoWindow
void setMapInfoWindow(){
    mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
        @Override
        public View getInfoWindow(Marker arg0) {
            return null;
        }

        @Override
        public View getInfoContents(Marker arg0) {
            View v = getLayoutInflater().inflate(R.layout.windowlayout, null);
            final ImageView img = (ImageView)v.findViewById(R.id.imageView3);
            //image
            Picasso.with(context).load("http://imgurl").resize(140, 
        }

    });
}

这是我的标记设置过程

void setMarkers(){
    ...

    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject datas=jsonArray.getJSONObject(i);
        MarkerOptions tmp=new MarkerOptions()
                .title("name")
                .alpha(0.6f)
                .position(new LatLng(123,456));//replace LatLng with sample
        marker=mMap.addMarker(tmp);

    }
    ....
    setMapInfoWindow();
}

完成Marker的设置后,调用setMapInfoWindow()函数。

它可以在我的智能手机上使用,但是当您第一次单击 infoWindow 时,它不会显示图像;但它会在第二次点击时显示。

我测试了一些情况:

  1. 将网页图片替换为本地图片,问题依旧。
  2. 将所有标记存储到ArrayList中,所有过程完成后,将所有标记设置为showInfoWindow(),然后将所有标记设置为hideInfoWindow()。它可以工作,但是有一个 infoWindow 无法关闭(最后一个)。
  3. 我正在尝试使用位图来获取图像,但它没有显示图像,我尝试了很多来自 stackoverflow 的方法。但在使用 Picasso 库时它可以工作。

谢谢

通过以下方式解决的问题: 加载时似乎 google 网络服务的图像 URL 将更改为另一个 URL。

示例:

https://maps.googleapis.com/maps/api/place/photo?photoreference=

它会被谷歌更改为以下网址:

https://lh4.googleusercontent.com/......

所以我将布尔 not_first_time_showing_info_window 更改为 int,并回调 3 次

    int not_first_time_showing_info_window=0;
    //show image
    try {
        if(not_first_time_showing_info_window==2){
            not_first_time_showing_info_window=0;
            Picasso.with(HomeActivity.this).load("http://....").resize(600,400).into(img);
        }
        else if (not_first_time_showing_info_window==1) {
            not_first_time_showing_info_window++;
            Picasso.with(HomeActivity.this).load("http://....").resize(600, 400).into(img,new InfoWindowRefresher(marker));
        }else if(not_first_time_showing_info_window==0){
            not_first_time_showing_info_window++;
            Picasso.with(HomeActivity.this).load("http://....").resize(600,400).into(img,new InfoWindowRefresher(marker));
        }
    } catch (Exception e) {
        img.setImageDrawable(null);
    }

【问题讨论】:

  • 所以如果你使用毕加索图书馆,第一次点击就会显示图像,对吧?
  • 不,第二次点击会显示使用毕加索库
  • 我通过 [this solution][1] 解决了这个问题,谢谢。 [1]:stackoverflow.com/a/22009558/2971851

标签: android google-maps google-maps-markers infowindow


【解决方案1】:

首先你可以创建一个自定义回调类来实现com.squareup.picasso.Callback

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

其次,在你的活动中声明一个布尔变量:

boolean not_first_time_showing_info_window;

三、实现public View getInfoContents(Marker marker)方法:

   @Override
   public View getInfoContents(Marker marker) {
      View v = getLayoutInflater().inflate(R.layout.custom_window, null);
      ImageView image = (ImageView)v.findViewById(R.id.image_view);

      if (not_first_time_showing_info_window) {
          Picasso.with(MainActivity.this).load("image_URL.png").into(image);

      } else {
          not_first_time_showing_info_window = true;                         
          Picasso.with(MainActivity.this).load("image_URL.png").into(image, new InfoWindowRefresher(marker));
      }
      return v;
   }

您也可以访问this GitHub page 以完成实施。

【讨论】:

  • 当调用“onSuccess”时,会导致整个应用程序停在“showInfoWindow”函数处(不崩溃),它不能做任何事情。我从“onSuccess”函数中删除了“showInfoWindow”,它可以工作(但我的问题仍然存在)。
  • 你所说的“停止”是什么意思?它是否在您的 logcat 中显示任何内容?还是您在 onSuccess 方法中设置了断点?
  • 另外,你所有的标记都放在同一个位置吗?您可以尝试在每个位置只放置一个标记,然后查看图像是否显示?
  • 我的标记位于不同的位置。 “停止”是指全屏停止,在信息窗口显示的那一刻停止,我不能触摸任何其他标记,直到显示系统消息才能触摸整个屏幕......“应用程序将关闭(中文)”。
  • 这可能不是一个好方法,它会调用showInfoWindow() 方法两次,每次单击标记。此外,如果您标记尝试下载大图像,下载可能需要 2 秒以上,因此postDelayed 仍将不显示任何图像。
【解决方案2】:

我认为 Google 一直在倾听,这是适合我的解决方案。在设置集群时,

getMap().setOnMapLoadedCallback(mOnMapLoaded);

一旦地图被加载,所有的标记都可以从集群管理器中获取,

private GoogleMap.OnMapLoadedCallback mOnMapLoaded = () -> {
    LogUtil.i(TAG, "Map has been loaded.");
    showInfoWindow();
};

private boolean showInfoWindow() {
    final WorkHeader selected = mWorkContainer.getSelectedHeader();
    Collection<Marker> markers = mClusterManager.getMarkerCollection().getMarkers();
    for (Marker marker : markers) {
        if (marker.getTitle().contains(selected.siteName)) {
            if (marker.getTitle().contains(selected.siteAddress)) {
                mClusterManager.onMarkerClick(marker);
                return true;
            }
        }
    }
    return false;
}

【讨论】:

    【解决方案3】:

    我在使用 Glide 而不是 Picasso 时遇到了同样的问题 但我做了一个简单的解决方案,我不知道它的效率如何,但它对我来说很好,无论如何我想与你分享它

    private Marker lastClicked;
    private HashSet<String> markerIdSet=new HashSet<>();
    
    @Override
    public boolean onMarkerClick(Marker marker) {
        lastClicked=marker;
        if(!markerIdSet.contains(marker.getId()))
        {
            marker.showInfoWindow();
            marker.hideInfoWindow();
            Handler handler=new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    lastClicked.showInfoWindow();
                }
            },150);
            markerIdSet.add(marker.getId());
            return true;
        }
        else
        {
            marker.showInfoWindow();
            return true;
        }
    }
    

    所以基本上你会创建一个 HashSet 的字符串(markerID) 如果 HashSet 不包含该标记 id,那么我们将其添加到 HashSet,并调用 marker.showInfoWindow(); 显示信息窗口并调用 marker.hideInfoWindow(); 隐藏它,然后使用 Handler 对象,代码执行将等待 150 毫秒,然后显示信息窗口调用再次marker.showInfoWindow();,这样做你会从第一次点击得到照片。

    从技术上讲,您是在强制代码在每个标记的第一次自动单击标记两次。

    如果有效,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-27
      • 2012-09-02
      • 2020-04-27
      • 2013-01-06
      • 2014-06-04
      • 1970-01-01
      • 2015-06-03
      • 2021-01-05
      相关资源
      最近更新 更多