如何使用 android-maps-utils 更改单击的标记图标?
Posted
技术标签:
【中文标题】如何使用 android-maps-utils 更改单击的标记图标?【英文标题】:How to change the clicked marker icon using android-maps-utils? 【发布时间】:2015-08-30 20:17:55 【问题描述】:在我的 android 项目中,我使用 android-maps-utils 库将聚类应用于地图视图上的一堆标记。每当单击标记时,我都会通过onClusterItemClick
收到通知,因此我可以执行一些操作。
public interface OnClusterItemClickListener<T extends ClusterItem>
public boolean onClusterItemClick(T item);
现在我想让用户知道点击了哪个标记。最简单的视觉反馈是更改标记图标的(颜色)。可以通过MarkerOptions
对象设置图标,该对象可以在onBeforeClusterItemRendered(T item, MarkerOptions markerOptions)
中访问,例如:
markerOptions.icon(
BitmapDescriptorFactory.defaultMarker(
BitmapDescriptorFactory.HUE_YELLOW));
如果我可以访问Marker
对象本身,例如onMarkerClick (Marker marker)
,我可以通过setIcon
更改图标。
如何更改点击的标记图标?
相关
How to highlight the selected cluster item? Android Google Map V2: How to change previous clicked marker's icon when clicked on another marker【问题讨论】:
【参考方案1】:我注意到DefaultClusterRenderer
提供了检索与ClusterItem
关联的Marker
对象的方法。因为无论如何我都使用自定义渲染器,所以我能够访问所需的 Marker
对象,如下所示:
mSelectedMarker = mCustomClusterItemRenderer.getMarker(mSelectedClusterItem);
这让我可以更改onClusterItemClick()
中的图标:
private void updateSelectedMarker()
if (mSelectedMarker != null)
mSelectedMarker.setIcon(
BitmapDescriptorFactory.defaultMarker(
BitmapDescriptorFactory.HUE_YELLOW));
【讨论】:
谢谢,点击其他项目后如何撤消更新? 不久前。我认为您需要在之前重置以前选择的标记或只迭代所有标记。 为了避免重复标记,我记住了最后一个选择的标记,并在更新下一个标记之前撤消了对最后一个标记的更改。谢谢 我只是这样做了,但图标没有改变。你们打电话给 mClusterManager.cluster() 吗? @KasparTr 你是怎么记住最后选择的标记的?【参考方案2】:感谢@JJD,我在 Kotlin 中写了同样的内容。
private var selectedBitmap: BitmapDescriptor? = null
private var unselectedBitmap: BitmapDescriptor? = null
private var lastMarker: Marker? = null
private var clusterManager: ClusterManager<StationClusterItem>? = null
override fun onMapReady(googleMap: GoogleMap)
this.googleMap = googleMap
clusterManager = ClusterManager(context!!, googleMap)
val clusterRenderer = MarkerClusterRenderer(context!!, googleMap, clusterManager!!,
unselectedBitmap!!)
clusterManager!!.renderer = clusterRenderer
// Add your items to the ClusterManager here with clusterManager?.addItem().
// Better is in background thread.
val boundsBuilder = LatLngBounds.Builder()
...
clusterManager!!.cluster()
// Add this listener to make ClusterManager correctly zoom clusters and markers.
googleMap.setOnCameraIdleListener(clusterManager)
// This method is needed to use setOnClusterItemClickListener.
googleMap.setOnMarkerClickListener(clusterManager)
clusterManager!!.setOnClusterItemClickListener item ->
lastMarker?.setIcon(unselectedBitmap)
lastMarker = clusterRenderer.getMarker(item) // Here we access a selected marker.
lastMarker?.setIcon(selectedBitmap)
// false - to show info window. See GoogleMap.InfoWindowAdapter.
// true - to hide info window.
false
class MarkerClusterRenderer(
val context: Context,
val map: GoogleMap,
clusterManager: ClusterManager<StationClusterItem>,
private val markerBitmap: BitmapDescriptor
) : DefaultClusterRenderer<StationClusterItem>(context, map, clusterManager)
init
minClusterSize = 1 // 2, 3 or more, as you wish.
override fun onBeforeClusterItemRendered(item: StationClusterItem?,
markerOptions: MarkerOptions?)
super.onBeforeClusterItemRendered(item, markerOptions)
markerOptions?.icon(markerBitmap)
更新
我遇到了一个异常:java.lang.IllegalArgumentException: Unmanaged descriptor
单击标记时(在一行 lastMarker?.setIcon(unselectedBitmap)
中)。
研究完IllegalArgumentException: Unmanaged descriptor using gms.maps.model.Marker.setIcon我重写了那个监听器:
private var selectedItem: StationClusterItem? = null
clusterManager!!.setOnClusterItemClickListener item ->
if (selectedItem != null)
// Set here a reference to a previous marker.
// We save a reference to a previous item, not to a marker.
val lastMarker = clusterRenderer.getMarker(selectedItem)
lastMarker?.setIcon(unselectedBitmap)
selectedItem = item
// Now get a reference to a selected marker.
val newMarker = clusterRenderer.getMarker(item)
newMarker?.setIcon(selectedBitmap)
false
【讨论】:
感谢IllegalArgumentException
的通知
@Vlad,谢谢!我也明白,setOnClusterItemClickListener
中的false
会影响信息窗口,请参阅***.com/a/60833015/2914140。【参考方案3】:
如果标记由于随机原因以编程方式未被选中(未选中),则之前的答案对我来说无法正常工作。
我将此代码添加到DefaultClusterRenderer
继承者
init
viewModel.selectedItem.observeForever
if (it == null)
clusterManager.cluster()
不要忘记在渲染器生命周期结束后销毁它。实际上,最好在渲染器之外使用。我在我的Activity
中使用它
private fun onMapClickListener()
if (viewModel.selectedItem.value != null) clusterManager.cluster()
以及默认图标更改代码(我这里只是切换图标颜色):
override fun onBeforeClusterItemRendered(item: ClusterMarker, markerOptions: MarkerOptions)
markerOptions.icon(getMarkerColor(item))
override fun onClusterItemUpdated(item: ClusterMarker, marker: Marker)
marker.setIcon(getMarkerColor(item))
private fun getMarkerColor(item: ClusterMarker): BitmapDescriptor
val color = if (item.id == viewModel.selectedItem.value?.id) BitmapDescriptorFactory.HUE_ORANGE
else item.getColor()
return BitmapDescriptorFactory.defaultMarker(color)
【讨论】:
以上是关于如何使用 android-maps-utils 更改单击的标记图标?的主要内容,如果未能解决你的问题,请参考以下文章
setTextAppearance() android-maps-utils 0.4.4 中的 TextView 始终透明
使用 Googles android-maps-utils 在最大缩放级别禁用集群
是否可以在特定标记 android-maps-utils 上对相机进行去簇和居中?
来自 android:android-maps-utils 的 ClusterManager 已更改且不兼容