作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想向谷歌地图显示自定义标记并将它们聚类。该标记包含一个 ImageView
,它将显示从网络下载的头像。这是我的目标:
然而,当我实现 Google Maps Android Marker Clustering Utility 时一切正常,ImageView
显示相同的头像(有时是两个错误的头像)。
这是我的自定义 MarkerRender:
public class MarkerRender extends DefaultClusterRenderer<Image> {
private static final String TAG = MarkerRender.class.getSimpleName();
private IconGenerator clusterGenerator;
private IconGenerator markerGenerator;
private ImageView mImgMarkerThumbnail;
private ImageView mImgMarkerClusterThumbnail;
private TextView txtSizeCluster;
private Activity activity;
private Bitmap mask, background;
private AtomicInteger imageDownloadCounter;
private int totalItem;
private ImageSize imageSize;
public MarkerRender(FragmentActivity activity, GoogleMap mMap, ClusterManager<Image> mClusterManager) {
super(activity, mMap, mClusterManager);
this.activity = activity;
imageDownloadCounter = new AtomicInteger(0);
mask = BitmapFactory.decodeResource(activity.getResources(),
R.drawable.annotation_behind);
background = BitmapFactory.decodeResource(activity.getResources(),
R.drawable.annotation_behind);
setUpClusterIcon();
setUpMarker();
}
private void setUpClusterIcon() {
clusterGenerator = new IconGenerator(activity);
View clusterView = activity.getLayoutInflater().inflate(R.layout.custom_marker_cluster, null);
txtSizeCluster = (TextView) clusterView.findViewById(R.id.tv_number_marker);
mImgMarkerClusterThumbnail = (ImageView) clusterView.findViewById(R.id.img_load);
clusterGenerator.setContentView(clusterView);
clusterGenerator.setBackground(null);
}
private void setUpMarker() {
markerGenerator = new IconGenerator(activity);
View markerView = activity.getLayoutInflater().inflate(R.layout.custom_marker, null);
mImgMarkerThumbnail = (ImageView) markerView.findViewById(R.id.img_load);
markerGenerator.setContentView(markerView);
markerGenerator.setBackground(null);
}
@Override
protected void onBeforeClusterItemRendered(final Image image, final MarkerOptions markerOptions) {
initImageSizeIfNeed();
Bitmap icon = markerGenerator.makeIcon();
PFLogManager.INSTANCE.logE(TAG, "maken icon: " + icon.hashCode());
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
icon.recycle();
}
@Override
protected void onClusterItemRendered(final Image image, Marker marker) {
super.onClusterItemRendered(image, marker);
ImageLoader.getInstance().loadImage(image.getMapImageLink(), imageSize,
new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Bitmap croppedBitmap = Helpers.makeCroppedBitmap(loadedImage, background, mask);
mImgMarkerThumbnail.setImageBitmap(croppedBitmap);
}
});
}
@Override
protected void onBeforeClusterRendered(Cluster<Image> cluster, MarkerOptions markerOptions) {
initImageSizeIfNeed();
Bitmap icon = clusterGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
icon.recycle();
}
@Override
protected void onClusterRendered(Cluster<Image> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
ArrayList<Image> list = new ArrayList<>(cluster.getItems());
setTextNumberMarker(cluster);
String urlFirstImage = list.get(0).getMapImageLink();
ImageLoader.getInstance().loadImage(urlFirstImage, imageSize,
new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
final Bitmap croppedBitmap = Helpers.makeCroppedBitmap(loadedImage, background, mask);
mImgMarkerClusterThumbnail.setImageBitmap(croppedBitmap);
}
});
}
private void loadClusterThumbnail(String url) {
}
private void setTextNumberMarker(Cluster<Image> cluster) {
int size = cluster.getSize();
if (size > 99) {
txtSizeCluster.setText("99+");
} else {
txtSizeCluster.setText(String.valueOf(cluster.getSize()));
}
}
@Override
protected boolean shouldRenderAsCluster(Cluster cluster) {
return cluster.getSize() > 1;
}
}
我猜问题是我只使用一个 ImageView
来显示这些头像,所以我尝试为每个标记使用唯一的 ImageView
(通过膨胀新标记从 xml 每次需要),但结果是它们都显示空白标记(只有背景,没有头像)。
最佳答案
我自己解决了。我的解决方案是使用 Marker.setIcon()
从网络下载或从缓存中获取图像后的方法。我不再使用 ImageView 了。
所以,我修改了上面的MarkerRender
类:setUpClusterIcon()
方法:
private void setUpClusterIcon() {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(markerWidth, markerHeight);
ImageView marker = new ImageView(activity);
marker.setLayoutParams(params);
clusterGenerator = new IconGenerator(activity);
clusterGenerator.setContentView(marker);
clusterGenerator.setBackground(null);
}
onClusterItemRendered()
方法:
protected void onClusterItemRendered(final Image image, final Marker marker) {
super.onClusterItemRendered(image, marker);
ImageLoader.getInstance().loadImage(image.getMapImageLink(), imageSize,
new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Bitmap croppedBitmap = Helpers.makeClusterItemBitmap(background, loadedImage, mask);
try {
marker.setIcon(BitmapDescriptorFactory.fromBitmap(croppedBitmap));
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
还有 makeClusterItemBitmap
辅助方法:
public static Bitmap makeClusterItemBitmap(Bitmap background, Bitmap original, Bitmap mask) {
Bitmap croppedOriginal = makeCroppedBitmap(original, mask);
Bitmap result = Bitmap.createBitmap(background.getWidth(), background.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
croppedOriginal = Bitmap.createScaledBitmap(croppedOriginal, croppedOriginal.getWidth() - 20, croppedOriginal.getHeight() - 20, true);
mCanvas.drawBitmap(background, 0, 0, null);
mCanvas.drawBitmap(croppedOriginal, 10, 10, null);
return result;
}
public static Bitmap makeCroppedBitmap(Bitmap original, Bitmap mask) {
original = Bitmap.createScaledBitmap(original, mask.getWidth(),
mask.getHeight(), true);
Bitmap result = Bitmap.createBitmap(original.getWidth(), original.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
return result;
}
完成,完成三天的噩梦研究日 :P
但是,这种方法会带来新的问题:性能
。由于绘制了很多层的新位图, map 有点滞后。我正在考虑改进这个:)
任何建议都是合适的:D
关于Android 谷歌地图显示自定义标记和聚类问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30231904/
leaflet:一个开源并且对移动端友好的交互式地图 JavaScript 库 中文文档: https://leafletjs.cn/reference.html 官网(英文): ht
我是一名优秀的程序员,十分优秀!