Mix*_*lis 18 android google-maps infowindow google-maps-api-2 loadimage
我正在使用Android应用程序.用户在谷歌地图上搜索餐馆.在谷歌地图显示所有邻居的餐厅标记.如果他点击标记,它会显示自定义InfoWindow.我的问题是我无法加载返回谷歌的图像.我正确的图像的网址,但我不能在窗口显示它.
信息窗口
<?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>
Run Code Online (Sandbox Code Playgroud)
在创造我有这个
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;
}
Run Code Online (Sandbox Code Playgroud)
});
而DownloadImage代码是:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,当我执行代码并点击标记时,getInfoContents不会停止执行,并且不会出现图标.
为什么会这样?
Dan*_*ray 37
我一直在构建一个类似的应用程序.
首先,InfoWindow没有显示下载图像的原因是因为MapFragment
将视图呈现为a Canvas
,然后绘制它.您在信息窗口中看到的不是您创建的视图,而是它们的"图片"或"屏幕截图".你基本上需要showInfoWindow()
再次调用该Marker
对象,这将重新渲染,Canvas
现在你的图像可见.
然而,话虽如此,根据我的经验,Bitmap
从URL 加载然后设置它不是最好的解决方案.Android不能Bitmap
很好地处理.加载几个位图后,OutOfMemoryError
异常只是时间问题,具体取决于您拥有的系统内存量.
我建议使用Picasso库来处理异步下载和缓存(在内存和磁盘中),并使实际图像只加载一行(Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
).(更多信息请访问http://square.github.io/picasso/)
之前的答案很好,除了正如他所说的那样,"延迟"对我来说有点太神奇了.Picasso可以选择使用回调,我建议使用它(我在我的应用程序中使用它).
首先创建一个实现Picasso Callback
接口的类(它可以在您的活动内部),并Marker
在构造函数中接收一个(因此您可以showInfoWindow()
再次调用该标记).
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() {}
}
Run Code Online (Sandbox Code Playgroud)
信息窗口如下所示:
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;
}
});
Run Code Online (Sandbox Code Playgroud)
你可以看到,回调非常简单.但是,当使用这种方法时,你必须小心只在第一次调用中使用回调,而不是在后续调用中使用(我只是not_first_time_showing_info_window
为了反映这个想法而设置...你必须看看如何将它包含在你的程序逻辑.如果你不这样做,Picasso回调将调用showInfoWindow()
,这将重新调用回调,这将召回showInfoWindow()
......好吧,你可以看到递归的去向.:)
主要的是让Picasso加载回调只运行一次,然后在后续调用中没有回调.
Mic*_*uff 10
我使用黑魔法(也就是设置延迟)解决了这个问题.我利用了Picasso的缓存,并在初始加载开始后几毫秒刚刚调用了showInfoWindow.
这是我的CustomWindowAdapter.
class CustomWindowAdapter implements InfoWindowAdapter{
LayoutInflater mInflater;
Map<Marker, String> imageStringMapMarker;
Context context;
public CustomWindowAdapter(LayoutInflater i, Map<Marker, String> imageStringMapMarker2, Context context ){
mInflater = i;
imageStringMapMarker = imageStringMapMarker2;
}
@Override
public View getInfoContents(final Marker marker) {
View v = mInflater.inflate(R.layout.custom_info_window, null);
ImageView ivThumbnail = (ImageView) v.findViewById(R.id.ivThumbnail);
String urlImage = imageStringMapMarker.get(marker).toString();
Picasso.with(context).load(Uri.parse(urlImage)).resize(250,250).into(ivThumbnail);
return v;
}
@Override
public View getInfoWindow(Marker marker) {
// TODO Auto-generated method stub
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
这是在我的主要活动中调用信息窗口的方法,我实现了延迟.
myMap.setInfoWindowAdapter(new CustomWindowAdapter(this.getLayoutInflater(),
imageStringMapMarker, getApplicationContext()));
myMap.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(final Marker mark) {
mark.showInfoWindow();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mark.showInfoWindow();
}
}, 200);
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
无论你从getInfoContents()
哪里返回,都会被转换为a Bitmap
并用于显示结果.直到稍后,下载完成时,您才会显示图像,此时Bitmap
已经创建并使用了该图像.
您需要getInfoContents()
在调用之前下载图像.
归档时间: |
|
查看次数: |
19466 次 |
最近记录: |