添加图像从URL到自定义信息窗口谷歌地图V2 [英] Add an Image from url into custom InfoWindow google maps v2

查看:240
本文介绍了添加图像从URL到自定义信息窗口谷歌地图V2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

林在工作中的一个Android应用程序。该用户进行的搜索在谷歌地图的餐馆。在谷歌地图显示标记为所有他的邻居的餐厅。如果他轻按一个标记它显示了一个自定义的信息窗口。我的问题是,我不能装入返回形成谷歌的地方的形象。即时得到图像的正确网址,但我不能在窗口中显示它。

Im am working in an android app. The user make a search at google maps for restaurants. In google map display markers for all of his neighbor's restaurant. If he tap at a marker it show up a custom InfoWindow. My problem is that i cant load the image that return form Google places. Im getting right the url of image but i can't show it at Window.

信息窗口

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/bg_color" >

<ImageView
        android:id="@+id/place_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="false"" />

<TextView
    android:id="@+id/place_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/place_vicinity"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<LinearLayout 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@color/bg_color" >

    <RatingBar
         android:id="@+id/place_rating"
         style="?android:attr/ratingBarStyleSmall"
         android:numStars="5"
         android:rating="0"
         android:isIndicator="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dip" />

    <ImageView
        android:id="@+id/navigate_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:src="@drawable/navigate" />

</LinearLayout>

在创建我有这个

mGoogleMap.setInfoWindowAdapter(new InfoWindowAdapter() {

            // Use default InfoWindow frame
            @Override
            public View getInfoWindow(Marker arg0) {
                return null;
            }

            // Defines the contents of the InfoWindow
            @Override
            public View getInfoContents(Marker arg0) {

                // Getting view from the layout file info_window_layout
                View v = getLayoutInflater().inflate(R.layout.info_window_layout, null);

                // Getting the snippet from the marker
                String snippet = arg0.getSnippet();

                // Getting the snippet from the marker
                String titlestr = arg0.getTitle();

                String cutchar1= "%#";
                String cutchar2= "%##";
                String ratingstr = snippet.substring(0,snippet.indexOf( cutchar1 ));
                String vicinitystr = snippet.substring(snippet.indexOf( cutchar1 )+2, snippet.indexOf( cutchar2 ) );
                String iconurl= snippet.substring(snippet.indexOf( cutchar2 )+3);

                // Getting reference to the TextView to set latitude
                TextView title = (TextView) v.findViewById(R.id.place_title);

                TextView vicinity = (TextView) v.findViewById(R.id.place_vicinity);

                ImageView image = (ImageView) v.findViewById(R.id.navigate_icon);

                // Setting the latitude
                title.setText(titlestr);

                // declare RatingBar object
                RatingBar rating=(RatingBar) v.findViewById(R.id.place_rating);// create RatingBar object
                if( !(ratingstr.equals("null")) ){
                    rating.setRating(Float.parseFloat(ratingstr));
                }
                vicinity.setText(vicinitystr);                  

                final DownloadImageTask download = new DownloadImageTask((ImageView) v.findViewById(R.id.place_icon) ,arg0);
                download.execute(iconurl);
                // Returning the view containing InfoWindow contents
                return v;

            }

});

和DownloadImage code是:

and the DownloadImage code is:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
      ImageView bmImage;
      Marker marker;
      boolean refresh;

      public DownloadImageTask(final ImageView bmImage, final Marker marker) {
          this.bmImage = bmImage;
          this.marker=marker;
          this.refresh=false;
      }

     public void SetRefresh(boolean refresh ){
         this.refresh=true;

     }

    /*  @Override
      protected void onPreExecute() 
      {
          super.onPreExecute();
          bmImage.setImageBitmap(null);
      }*/

      @Override
      protected Bitmap doInBackground(String... urls) {
          String urldisplay = urls[0];
          Bitmap mIcon11 = null;
          try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
          } catch (Exception e) {
              Log.e("Error", e.getMessage());
              e.printStackTrace();
          }
          return mIcon11;
      }
      @Override
      protected void onPostExecute(Bitmap result) {
          if(!refresh){
              SetRefresh(refresh);
              bmImage.setImageBitmap(result);
              marker.showInfoWindow();
          }
      }
    }

最后,当我执行code和挖掘标记的getInfoContents犯规停止执行和图标不会出现。

Finally when i execute the code and tap the marker the getInfoContents doesnt stop execute and the icon does not appear.

有没有人任何想法,为什么出现这种情况?请帮我.... 谢谢advace !!

Has anybody any idea, why this happen?? Please help me.... Thanks in advace!!

推荐答案

我已经建立了类似的应用程序。

I've been building a similar app.

首先,你的信息窗口没有显示已下载的图像的原因是因为 MapFragment 渲染视图成画布,然后绘制的。你看到的信息窗口中什么都没有,你创建的视图,但图片报和他们的屏幕截图。你基本上需要 showInfoWindow()再次调用标记对象,这将重新渲染画布和你的形象现在是可见的。

First of all, the reason your InfoWindow is not showing the downloaded image is because the MapFragment renders the view into a Canvas, and then draws that. What you're seeing in the info window aren't the views you created, but a "picture" or "screenshot" of them. You basically need to call showInfoWindow() again on the Marker object, and that will re-render the Canvas and your image will now be visible.

不过,话虽如此,在我的经验,从URL加载位图,然后设置它是不是最好的解决方案。 Android不处理位图 s甚好。加载多个位图后,一个的OutOfMemoryError 的例外是只是一个时间问题,这取决于系统内存你有多少。

However, that being said, in my experience loading the Bitmap from the URL and then setting it isn't the best solution. Android doesn't handle Bitmaps very well. After loading several bitmaps, an OutOfMemoryError exception is just a matter of time, depending on the amount of system memory you have.

我会建议使用毕加索库,它处理异步下载和缓存(在内存和磁盘),使实际的图像加载只有一行( Picasso.with(上下文).load (http://i.imgur.com/DvpvklR.png)。走进(ImageView的); )。 (在 http://square.github.io/picasso/ 详细信息)

I'd recommend using the Picasso library, which handles the asynchronous downloading, and caching (in memory and disk) and makes the actual image loading just one line (Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);). (more info at http://square.github.io/picasso/)

在previous的回答是不错的,只是因为他说过,拖延是有点太不可思议了我的口味。毕加索具有使用回调的选项,我建议你使用(我使用的,在我的应用程序)。

The previous answer was good, except that as he said, that "delay" is a little bit too magical for my taste. Picasso has the option of using callbacks, and I'd recommend using that (I'm using that in my app).

首先创建一个类(也可以是内部的活动),实现毕加索的回调接口,并接收标记在构造函数(这样你就可以调用 showInfoWindow()上标记了。

First create a class (it can be internal to your activity) that implements Picasso's Callback interface, and receives a Marker in the constructor (so you can call showInfoWindow() on that marker again.

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

信息窗口看起来是这样的:

The info window looks like this:

mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
    @Override
    public View getInfoWindow(Marker marker) {
        // inflate view window

        // set other views content

        // set image view like this:
        if (not_first_time_showing_info_window) {
            Picasso.with(ActivityClass.this).load(restaurantPictureURL).into(imgInfoWindowPicture);
        } else { // if it's the first time, load the image with the callback set
            not_first_time_showing_info_window=true;
            Picasso.with(ActivityClass.this).load(restaurantPictureURL).into(imgInfoWindowPicture,new InfoWindowRefresher(marker));
        }

        return v;
    }

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

回调是pretty的简单,你可以看到。但是,使用这种方法,您时,一定要小心只使用回调的第一个电话,而不是在后续调用(我只是把在 not_first_time_showing_info_window 反映的想法......你必须来看看如何包含在你的程序逻辑。如果你不这样做,毕加索回调将调用 showInfoWindow(),这将重新调用回调,这将召回 showInfoWindow() ...好了,你能看到的递归的打算:。)

The callback is pretty simple, as you can see. However, when using this method you MUST be careful to only use the callback in the first call, and not in subsequent calls (I just put in that not_first_time_showing_info_window to reflect the idea... you'll have to see how to include that in your program logic. If you don't do that, the Picasso callback will call showInfoWindow() and that will re-call the callback, which will recall showInfoWindow()... well, you can see where that recursion's going. :)

更主要的是让毕加索负荷回调只运行一次,并在随后的电话,避免回调。

The main thing is getting the Picasso load with the callback to only run once, and on the subsequent calls, without the callback.

这篇关于添加图像从URL到自定义信息窗口谷歌地图V2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆