添加图像从URL到自定义信息窗口谷歌地图V2 [英] Add an Image from url into custom InfoWindow google maps 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 Bitmap
s 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屋!