Android Google 使用动态图像映射集群项目标记 URL - 用所有标记覆盖 URL
Android Google map Cluster Item marker with dynamic image URL - overwrite URL with all marker
在我的地图上有集群的应用程序中,Top/Main 集群标记显示标记总数,点击显示所有子集群项目标记。
在集群项(子集群标记)中显示具有不同颜色的圆形背景,并且在显示来自 URL 的图像(从 Web 服务响应中获取)之间,集群项正确显示图像但是
我的问题是在刷新最后一个响应图像 URL 后用所有标记图像覆盖,意味着
所有集群项目显示相同的图像而不是不同的图像。
请任何人帮助解决这个覆盖问题。我的代码如下。
private class RenderClusterInfoWindow extends DefaultClusterRenderer<ModelClusterBikeList> {
private final IconGenerator mClusterIconGenerator = new IconGenerator(getActivity());
private final IconGenerator iconGenerator = new IconGenerator(getActivity());
ImageView imageView;
int markerWidth;
int markerHeight;
private DisplayImageOptions options;
RenderClusterInfoWindow(Activity context, GoogleMap map, ClusterManager<ModelClusterBikeList> clusterManager) {
super(context, map, clusterManager);
// Main inflate view it show number data available inside cluster
View multiProfile = getLayoutInflater().inflate(R.layout.inflate_cluster, null);
mClusterIconGenerator.setContentView(multiProfile);
markerWidth = (int) context.getResources().getDimension(R.dimen.custom_profile_image);
markerHeight = (int) context.getResources().getDimension(R.dimen.custom_profile_image);
// inflator its show image from the response url. (cluster item)
View clusterITEM = getLayoutInflater().inflate(R.layout.inflate_cluster_item, null);
iconGenerator.setContentView(clusterITEM);
imageView = clusterITEM.findViewById(R.id.imageClusterPIN);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(markerWidth, markerHeight);
layoutParams.gravity = Gravity.CENTER;
imageView.setLayoutParams(layoutParams);
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(getActivity()));
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.mipmap.image_icn)
.showImageOnFail(R.mipmap.image_icn)
.cacheInMemory(false)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
}
@Override
protected boolean shouldRenderAsCluster(Cluster<ModelClusterBikeList> cluster) {
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (googleMap.getCameraPosition().zoom > 19.0) {
setClusterSize = 2;
} else {
setClusterSize = 4;
}
}
});
}
if (setClusterSize == 2) {
return cluster.getSize() > cluster.getSize();
} else {
return cluster.getSize() > setClusterSize;
}
}
@Override
protected void onClusterRendered(Cluster<ModelClusterBikeList> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
}
@Override
protected void onBeforeClusterItemRendered(ModelClusterBikeList item, MarkerOptions markerOptions) {
iconGenerator.setBackground(
ContextCompat.getDrawable(getActivity(), R.drawable.round_asset));
ImageLoader.getInstance().displayImage(item.getAssets_img_url(), imageView, options);
// Issue is here , overwrite image url here with all marker./cluster item.
Bitmap icon = iconGenerator.makeIcon(item.getAssets_img_url());
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
markerOptions.title(item.getId());
markerOptions.draggable(true);
super.onBeforeClusterItemRendered(item, markerOptions);
}
@Override
protected void onBeforeClusterRendered(Cluster<ModelClusterBikeList> cluster, MarkerOptions markerOptions) {
mClusterIconGenerator.setBackground(null);
Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
}
@Override
protected void onClusterItemRendered(ModelClusterBikeList clusterItem, Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
}
}
我也尝试将 "onBeforeClusterItemRendered" 的所有代码放入 onClusterItemRendered 但得到相同的结果,相同的覆盖最后 url 包含所有杂乱项。
你好@Topsy 按照下面的方法更改代码,它会为你工作。
首先将 onBeforeClusterItemRendered 方法替换为以下代码。
@Override
protected void onBeforeClusterItemRendered(ModelClusterBikeList item, MarkerOptions
markerOptions) {
icon = iconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).
title(item.getAssets_img_url());
markerOptions.title(item.getId());
markerOptions.draggable(true);
super.onBeforeClusterItemRendered(item, markerOptions);
}
然后将 onClusterItemRendered 方法替换为以下代码。
@Override
protected void onClusterItemRendered(ModelClusterBikeList clusterItem, Marker
marker) {
if (getActivity() != null) {
Glide.with(getActivity())
.asBitmap()
.load(clusterItem.getAssets_img_url())
.error(R.drawable.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable
Transition<? super Bitmap> transition) {
try {
if (googleMap != null) {
iconGenerator.setBackground(
ContextCompat.getDrawable(getActivity(),
R.drawable.round_asset));
imageView.setImageBitmap(resource);
imageView.buildDrawingCache();
Bitmap icon = iconGenerator.makeIcon();
if (icon != null) {
marker.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
}
这是一个使用 Kotlin、Coroutine 和 Coil 的更新解决方案:
class Custom(
private val coroutineScope: CoroutineScope,
private val context: Context,
private val map: GoogleMap,
clusterManager: ClusterManager<CustomMapItem>?,
) : DefaultClusterRenderer<CustomMapItem>(context, map, clusterManager), GoogleMap.OnCameraIdleListener {
var itemId: String? = null
private val iconFactory = IconGenerator(context)
private var currentZoomLevel = 0f
private var maxZoomLevel = 0f
/**
* Method called right after the cluster item (the marker) is rendered.
* This is where properties for the Marker object should be set.
*/
override fun onClusterItemRendered(clusterItem: CustomMapItem, marker: Marker) {
super.onClusterItemRendered(clusterItem, marker)
marker.tag = clusterItem
coroutineScope.launch {
val drawable: Drawable = checkNotNull(
context.imageLoader.execute(
ImageRequest.Builder(context)
.data(clusterItem.item.imageUrl)
.fallback(R.drawable.ui_img_default_profile)
.error(R.drawable.ui_img_default_profile)
.diskCachePolicy(CachePolicy.ENABLED)
.allowHardware(false)
.build(),
).drawable,
)
val imageView = ImageView(context).apply {
setImageDrawable(drawable)
scaleType = ImageView.ScaleType.CENTER_CROP
layoutParams = ViewGroup.LayoutParams(PROFILE_PICTURE_SIZE_IN_DP.toPxSize, PROFILE_PICTURE_SIZE_IN_DP.toPxSize)
}
iconFactory.setContentView(imageView)
marker.setIcon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon()))
if (clusterItem.item.id == itemId) {
marker.showInfoWindow()
}
}
}
override fun onCameraIdle() {
currentZoomLevel = map.cameraPosition.zoom
maxZoomLevel = map.maxZoomLevel
}
override fun shouldRenderAsCluster(cluster: Cluster<CustomMapItem>): Boolean {
// Detect overlapped ege case
if (currentZoomLevel >= maxZoomLevel - 1 && cluster.size > 1) {
var zIndex = 1
for (item in cluster.items) {
item.zIndex = zIndex++
}
}
return currentZoomLevel < maxZoomLevel - 1 && cluster.size > 1
}
companion object {
private const val PROFILE_PICTURE_SIZE_IN_DP = 48
}
}
在我的地图上有集群的应用程序中,Top/Main 集群标记显示标记总数,点击显示所有子集群项目标记。
在集群项(子集群标记)中显示具有不同颜色的圆形背景,并且在显示来自 URL 的图像(从 Web 服务响应中获取)之间,集群项正确显示图像但是 我的问题是在刷新最后一个响应图像 URL 后用所有标记图像覆盖,意味着 所有集群项目显示相同的图像而不是不同的图像。
请任何人帮助解决这个覆盖问题。我的代码如下。
private class RenderClusterInfoWindow extends DefaultClusterRenderer<ModelClusterBikeList> {
private final IconGenerator mClusterIconGenerator = new IconGenerator(getActivity());
private final IconGenerator iconGenerator = new IconGenerator(getActivity());
ImageView imageView;
int markerWidth;
int markerHeight;
private DisplayImageOptions options;
RenderClusterInfoWindow(Activity context, GoogleMap map, ClusterManager<ModelClusterBikeList> clusterManager) {
super(context, map, clusterManager);
// Main inflate view it show number data available inside cluster
View multiProfile = getLayoutInflater().inflate(R.layout.inflate_cluster, null);
mClusterIconGenerator.setContentView(multiProfile);
markerWidth = (int) context.getResources().getDimension(R.dimen.custom_profile_image);
markerHeight = (int) context.getResources().getDimension(R.dimen.custom_profile_image);
// inflator its show image from the response url. (cluster item)
View clusterITEM = getLayoutInflater().inflate(R.layout.inflate_cluster_item, null);
iconGenerator.setContentView(clusterITEM);
imageView = clusterITEM.findViewById(R.id.imageClusterPIN);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(markerWidth, markerHeight);
layoutParams.gravity = Gravity.CENTER;
imageView.setLayoutParams(layoutParams);
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(getActivity()));
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.mipmap.image_icn)
.showImageOnFail(R.mipmap.image_icn)
.cacheInMemory(false)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
}
@Override
protected boolean shouldRenderAsCluster(Cluster<ModelClusterBikeList> cluster) {
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (googleMap.getCameraPosition().zoom > 19.0) {
setClusterSize = 2;
} else {
setClusterSize = 4;
}
}
});
}
if (setClusterSize == 2) {
return cluster.getSize() > cluster.getSize();
} else {
return cluster.getSize() > setClusterSize;
}
}
@Override
protected void onClusterRendered(Cluster<ModelClusterBikeList> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
}
@Override
protected void onBeforeClusterItemRendered(ModelClusterBikeList item, MarkerOptions markerOptions) {
iconGenerator.setBackground(
ContextCompat.getDrawable(getActivity(), R.drawable.round_asset));
ImageLoader.getInstance().displayImage(item.getAssets_img_url(), imageView, options);
// Issue is here , overwrite image url here with all marker./cluster item.
Bitmap icon = iconGenerator.makeIcon(item.getAssets_img_url());
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
markerOptions.title(item.getId());
markerOptions.draggable(true);
super.onBeforeClusterItemRendered(item, markerOptions);
}
@Override
protected void onBeforeClusterRendered(Cluster<ModelClusterBikeList> cluster, MarkerOptions markerOptions) {
mClusterIconGenerator.setBackground(null);
Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
}
@Override
protected void onClusterItemRendered(ModelClusterBikeList clusterItem, Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
}
}
我也尝试将 "onBeforeClusterItemRendered" 的所有代码放入 onClusterItemRendered 但得到相同的结果,相同的覆盖最后 url 包含所有杂乱项。
你好@Topsy 按照下面的方法更改代码,它会为你工作。
首先将 onBeforeClusterItemRendered 方法替换为以下代码。
@Override
protected void onBeforeClusterItemRendered(ModelClusterBikeList item, MarkerOptions
markerOptions) {
icon = iconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).
title(item.getAssets_img_url());
markerOptions.title(item.getId());
markerOptions.draggable(true);
super.onBeforeClusterItemRendered(item, markerOptions);
}
然后将 onClusterItemRendered 方法替换为以下代码。
@Override
protected void onClusterItemRendered(ModelClusterBikeList clusterItem, Marker
marker) {
if (getActivity() != null) {
Glide.with(getActivity())
.asBitmap()
.load(clusterItem.getAssets_img_url())
.error(R.drawable.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable
Transition<? super Bitmap> transition) {
try {
if (googleMap != null) {
iconGenerator.setBackground(
ContextCompat.getDrawable(getActivity(),
R.drawable.round_asset));
imageView.setImageBitmap(resource);
imageView.buildDrawingCache();
Bitmap icon = iconGenerator.makeIcon();
if (icon != null) {
marker.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
}
这是一个使用 Kotlin、Coroutine 和 Coil 的更新解决方案:
class Custom(
private val coroutineScope: CoroutineScope,
private val context: Context,
private val map: GoogleMap,
clusterManager: ClusterManager<CustomMapItem>?,
) : DefaultClusterRenderer<CustomMapItem>(context, map, clusterManager), GoogleMap.OnCameraIdleListener {
var itemId: String? = null
private val iconFactory = IconGenerator(context)
private var currentZoomLevel = 0f
private var maxZoomLevel = 0f
/**
* Method called right after the cluster item (the marker) is rendered.
* This is where properties for the Marker object should be set.
*/
override fun onClusterItemRendered(clusterItem: CustomMapItem, marker: Marker) {
super.onClusterItemRendered(clusterItem, marker)
marker.tag = clusterItem
coroutineScope.launch {
val drawable: Drawable = checkNotNull(
context.imageLoader.execute(
ImageRequest.Builder(context)
.data(clusterItem.item.imageUrl)
.fallback(R.drawable.ui_img_default_profile)
.error(R.drawable.ui_img_default_profile)
.diskCachePolicy(CachePolicy.ENABLED)
.allowHardware(false)
.build(),
).drawable,
)
val imageView = ImageView(context).apply {
setImageDrawable(drawable)
scaleType = ImageView.ScaleType.CENTER_CROP
layoutParams = ViewGroup.LayoutParams(PROFILE_PICTURE_SIZE_IN_DP.toPxSize, PROFILE_PICTURE_SIZE_IN_DP.toPxSize)
}
iconFactory.setContentView(imageView)
marker.setIcon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon()))
if (clusterItem.item.id == itemId) {
marker.showInfoWindow()
}
}
}
override fun onCameraIdle() {
currentZoomLevel = map.cameraPosition.zoom
maxZoomLevel = map.maxZoomLevel
}
override fun shouldRenderAsCluster(cluster: Cluster<CustomMapItem>): Boolean {
// Detect overlapped ege case
if (currentZoomLevel >= maxZoomLevel - 1 && cluster.size > 1) {
var zIndex = 1
for (item in cluster.items) {
item.zIndex = zIndex++
}
}
return currentZoomLevel < maxZoomLevel - 1 && cluster.size > 1
}
companion object {
private const val PROFILE_PICTURE_SIZE_IN_DP = 48
}
}