在Google Maps Android API v2中使用文本标记标记

时间:2013-07-24 14:50:02

标签: android google-maps google-maps-markers google-maps-android-api-2

我已经提到了这篇文章,但它适用于已弃用的Google Maps API

http://tech.truliablog.com/2012/02/23/custom-map-markers-for-android-google-maps/

在新的API中,我找不到一种简单的方法来执行此操作。事实上,我完全不能这样做。

基本上我想在地图上将TextViews作为标记使用9Patch drawable作为文本的背景。 Trulia仍然在他们当前的应用程序中使用新的API v2。你可以在这里查看

Trulia current app

我该怎么做?

7 个答案:

答案 0 :(得分:34)

Chris Broadfoot创建了一个实用程序库。

图书馆可在此处找到:https://github.com/googlemaps/android-maps-utils

另请参阅此简短视频:http://www.youtube.com/watch?v=nb2X9IjjZpM

答案 1 :(得分:6)

可以使用谷歌提供的这个有用的库来简单地实现。

IconGenerator icg = new IconGenerator(this);
icg.setColor(Color.GREEN); // green background 
icg.setTextAppearance(R.style.BlackText); // black text 
Bitmap bm = icg.makeIcon("200 mi");

在style.xml中

<style name="BlackText" parent="TextDefault">
    <item name="android:textColor">@color/black</item>
</style>

http://googlemaps.github.io/android-maps-utils/javadoc/

http://googlemaps.github.io/android-maps-utils/

https://github.com/googlemaps/android-maps-utils

答案 2 :(得分:5)

据我所知,google maps api v2目前不支持此功能。 另一方面,您可以做的是动态创建标记的位图,并写入要在其中显示的值。唉,如果你碰巧有足够的针脚,可能很容易出现性能问题。

Canvas canvas = new Canvas(bitmap);
canvas.drawText("Your text", textXOffset, textYOffset, mPictoPaint);
MarkerOptions options = new MarkerOptions().position([…]).icon(BitmapDescriptorFactory.fromBitmap(bitmapResult));
Marker newMarker = map.addMarker(options);

请注意bitmap需要是可变的。此外,您还必须根据需要缩放基本图像(可能使用9.patch)。

答案 3 :(得分:1)

我知道这个问题很旧,但是如果有帮助,我会在这里发布答案。

以上解决方案均不适用于我,因为

  • 我的应用程序中已经有用于标记的自定义图标

  • 我的应用程序可能显示成千上万种不同的标记标题,因此在内存中创建许多图像会带来性能问题

  • 随着标记图标变大,地图很快变得不可读

  • 我希望标题仅在有空间时显示,如果没有足够的空间显示,可能会隐藏

我在互联网上找不到任何解决方案,所以我袖手旁观,制作了可以解决我的问题的库,希望它也可以对其他人有所帮助:

https://github.com/androidseb/android-google-maps-floating-marker-titles

以下是其工作原理的预览:

preview

答案 4 :(得分:0)

通过引用Google's sample code

IconGenerator iconFactory = new IconGenerator(this);    
        iconFactory.setColor(Color.CYAN);
        addIcon(mMap, iconFactory, "Custom color", new LatLng(-33.9360, 151.2070));

addIcon()方法在这里:

private void addIcon(GoogleMap googleMap, IconGenerator iconFactory, CharSequence text, LatLng position) {
        MarkerOptions markerOptions = new MarkerOptions().
                icon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon(text))).
                position(position).
                anchor(iconFactory.getAnchorU(), iconFactory.getAnchorV());

        googleMap.addMarker(markerOptions);
    }

答案 5 :(得分:0)

如果您使用Clusters,则行为会稍有不同。

我看着https://medium.com/@yilmazvolkan/custom-map-marker-8b136212d766,是这样写的。

styles.xml:

<!-- Google Maps marker -->
<style name="MarkerText">
    <item name="android:textSize">12sp</item>
    <item name="android:textColor">#f0f0f0</item>
</style>

marker_bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >

    <solid android:color="#3232a0" />
    <corners android:radius="18dp" />
</shape>

片段:

private var clusterManager: ClusterManager<SomeClusterItem>? = null
private var clusterRenderer: MarkerClusterRenderer<SomeClusterItem>? = null
private var unselectedBitmap: BitmapDescriptor? = null
private var iconGenerator: IconGenerator? = null
private var selectedItem: SomeClusterItem? = null

override fun onMapReady(googleMap: GoogleMap) {
    this.googleMap = googleMap
    ...

    unselectedBitmap =
        BitmapUtils.bitmapDescriptorFromVector(context!!, R.drawable.unselected_item)

    // Create a text marker background.
    iconGenerator = IconGenerator(context!!)
    iconGenerator!!.setTextAppearance(R.style.MarkerText)
    val markerBackground = ContextCompat.getDrawable(context!!, R.drawable.marker_bg)
    iconGenerator!!.setBackground(markerBackground)

    clusterManager = ClusterManager(context!!, googleMap)
    clusterRenderer = MarkerClusterRenderer(context!!, googleMap, clusterManager!!,
        unselectedBitmap!!)
    clusterManager!!.renderer = clusterRenderer

    ...
    // Create a list of markers.
    val boundsBuilder = LatLngBounds.Builder()
    ...

    // Show clusters and markers.
    clusterManager!!.cluster()

    clusterManager!!.setOnClusterItemClickListener { item ->
        // Deselect selected marker.
        // See https://stackoverflow.com/a/53829888/2914140.
        if (selectedItem != null) {
            deselectMarker(selectedItem)
        }
        selectedItem = item
        selectMarker(selectedItem!!, iconGenerator)
        // Show info window. See GoogleMap.InfoWindowAdapter.
        false
    }
    clusterManager!!.setOnClusterClickListener {
        deselectMarker(selectedItem)
        true
    }


private fun selectMarker(item: SomeClusterItem,
                         iconGenerator: IconGenerator) {
    // Generate a text marker.
    val icon = iconGenerator.makeIcon(item.title)
    val bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(icon)
    clusterRenderer?.getMarker(item)?.setIcon(bitmapDescriptor)
}

private fun deselectMarker(item: SomeClusterItem?) =
    clusterRenderer?.getMarker(item)?.setIcon(unselectedBitmap)

然后您将看到这些图片(未选择所有项目,而是选择了一项)。

enter image description here enter image description here

请注意,显示了InfoWindow。要自定义信息窗口,请参见https://stackoverflow.com/a/59952706/2914140

要删除信息窗口,只需以适当的方法返回true(请参阅Hide markers info window in android google maps API v2)。

clusterManager!!.setOnClusterItemClickListener { item ->
    ...
    true
}

enter image description here

答案 6 :(得分:0)

一个有效的解决方案。 对于 MarkerOptions 对象:

        markerOptions = new MarkerOptions()
                .position(posPrm)
                .title("" + order_id)
                .snippet(sLcl2)
                icon(giveMeBitmapDescriptor(mapsActivity,R.drawable.route_marker))
        ;

和方法:

private BitmapDescriptor giveMeBitmapDescriptor(Context context,
        int iconPrm) {
    Drawable background = ContextCompat.getDrawable(context, iconPrm);
    background.setBounds(0, 0, background.getIntrinsicWidth(), background.getIntrinsicHeight());
    Bitmap bitmap = Bitmap.createBitmap(background.getIntrinsicWidth(), background.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    background.draw(canvas);
    Rect r = new Rect();
    canvas.getClipBounds(r);
    int cHeight = r.height();
    int cWidth = r.width();
    Paint paint = new Paint();
    paint.setTextAlign(Paint.Align.LEFT);
    paint.getTextBounds("text", 0, "text".length(), r);
    float x = cWidth / 2f - r.width() / 2f - r.left;
    float y = cHeight / 2f + r.height() / 2f - r.bottom;
    canvas.drawText("text", x, y, paint);
    return BitmapDescriptorFactory.fromBitmap(bitmap);
}

此操作也应在 UI 线程中运行 否则它不会声明任何内容并绘制没有文字的图标。