21

我想出了这篇文章,但它是针对已弃用的 Google Maps API

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

在新的 API 中,我找不到一个简单的方法来做到这一点。事实上,我根本做不到。

基本上,我希望将 TextViews 作为地图上的标记,并将 9Patch 可绘制作为文本的背景。Trulia 仍在其当前应用程序中使用新的 API v2 进行此操作。你可以在这里查看

Trulia 当前应用

我怎样才能做到这一点?

4

7 回答 7

40

Chris Broadfoot创建了一个实用程序库,正是这样做的。

该库可在此处获得:https ://github.com/googlemaps/android-maps-utils

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

于 2013-07-24T18:31:21.010 回答
17

使用 google 提供的这个有用的库可以简单地实现它。

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

您可以从此链接在项目中设置上层链接

于 2017-10-26T14:28:24.070 回答
6

据我所知,谷歌地图 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)。

于 2013-07-24T15:23:20.300 回答
5

我知道这个问题很老,但我会在这里发布我的答案,以防它帮助某人。

以上解决方案都不适合我,因为

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

  • 我的应用程序可能会显示数千个不同的标记标题,因此在内存中创建这么多图像将是一个性能问题

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

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

我在互联网上没有找到解决方案,所以我卷起袖子制作了这个库来解决我的问题,希望它也能帮助其他人:

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

这是它如何工作的预览:

预览

于 2018-08-12T18:10:48.900 回答
2

通过参考谷歌的示例代码

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);
    }
于 2019-10-01T02:31:39.980 回答
0

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

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

样式.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)

然后你会看到这些图片(所有项目都没有被选中,只有一个项目被选中)。

在此处输入图像描述 在此处输入图像描述

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

要删除信息窗口,只需true以适当的方法返回(请参阅在 android google maps API v2 中隐藏标记信息窗口)。

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

在此处输入图像描述

于 2020-03-24T14:24:33.533 回答
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 线程中运行,否则它不会声明任何内容并在其上绘制没有文本的图标。

于 2021-04-06T18:46:26.453 回答