带有自定义标记的android Maps API v2

问题描述 投票:64回答:9

我想用自定义标记制作地图。在API v2中,我可以为标记设置图标,标题等。但我想在第一次出现时用标记显示标题。现在只有在我点击标记时才会显示标题。在v1中是覆盖,但在v2中我没有发现任何类似的东西。

编辑:也许我不够清楚。 API中的Marker.showInfoWindow()之类的东西仅适用于一个标记。我无法同时显示所有标记的信息窗口。无论如何,我需要为我的所有标记显示标题,而无需等待用户点击它。

android google-maps google-maps-android-api-2
9个回答
83
投票

我也偶然发现了这个问题。 V2 API是向前迈出的一步,后退两步。谷歌,请在Marker或GoogleMap类上添加一个可覆盖的'draw'方法,以便我们自己定制绘图。

一种可能的解决方案是动态生成位图并将其附加到标记。即创建画布,插入标记位图,在标记旁边绘制文本。这涉及一些痛苦的计算(适当的画布大小与标记位图和文本彼此相邻)。不幸的是,Marker中没有setIcon方法,因此每次文本更改时,都必须创建一个新标记。如果您在地图上只有一个标记可能没问题,但是有几十个标记,这可能不太可行。此外,动态创建这些位图可能存在内存问题。示例代码(仅包含文本):

Bitmap.Config conf = Bitmap.Config.ARGB_8888; 
Bitmap bmp = Bitmap.createBitmap(200, 50, conf); 
Canvas canvas = new Canvas(bmp);

canvas.drawText("TEXT", 0, 50, paint); // paint defines the text color, stroke width, size
mMap.addMarker(new MarkerOptions()
                                .position(clickedPosition)
                                //.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker2))
                                .icon(BitmapDescriptorFactory.fromBitmap(bmp))
                                .anchor(0.5f, 1)
                                    );

希望Google能够添加适当的方法,以便我们轻松完成。该死的,我真的很喜欢V2 API中新的Map旋转功能。


48
投票

终于做到了。所以你做的是有一个背景图像(在我的情况下,我只使用一个蓝色矩形)。像这样创建一个标记:

Marker myLocMarker = map.addMarker(new MarkerOptions()
            .position(myLocation)
            .icon(BitmapDescriptorFactory.fromBitmap(writeTextOnDrawable(R.drawable.bluebox, "your text goes here"))));

注意writeTextOnDrawable()方法:

private Bitmap writeTextOnDrawable(int drawableId, String text) {

    Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId)
            .copy(Bitmap.Config.ARGB_8888, true);

    Typeface tf = Typeface.create("Helvetica", Typeface.BOLD);

    Paint paint = new Paint();
    paint.setStyle(Style.FILL);
    paint.setColor(Color.WHITE);
    paint.setTypeface(tf);
    paint.setTextAlign(Align.CENTER);
    paint.setTextSize(convertToPixels(context, 11));

    Rect textRect = new Rect();
    paint.getTextBounds(text, 0, text.length(), textRect);

    Canvas canvas = new Canvas(bm);

    //If the text is bigger than the canvas , reduce the font size
    if(textRect.width() >= (canvas.getWidth() - 4))     //the padding on either sides is considered as 4, so as to appropriately fit in the text
        paint.setTextSize(convertToPixels(context, 7));        //Scaling needs to be used for different dpi's

    //Calculate the positions
    int xPos = (canvas.getWidth() / 2) - 2;     //-2 is for regulating the x position offset

    //"- ((paint.descent() + paint.ascent()) / 2)" is the distance from the baseline to the center.
    int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;  

    canvas.drawText(text, xPos, yPos, paint);

    return  bm;
}



public static int convertToPixels(Context context, int nDP)
{
    final float conversionScale = context.getResources().getDisplayMetrics().density;

    return (int) ((nDP * conversionScale) + 0.5f) ;

}

感谢Arun George:Add text to image in android programmatically


15
投票

似乎您的问题最终在Google I / O会话中得到了解答。

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

它有:

标记聚类 - 处理大量点的显示

热图 - 显示大量的点作为热图

IconGenerator - 在你的标记上显示文字(见截图)

非常重要的是,它可以在任何线程上进行修改,因此处理许多标记是轻而易举的


9
投票

我不确定你想要实现的目标:让信息窗口显示而用户不必点击标记,或者使用完全不同的信息窗口视图(或者两者都有)。

要显示信息窗口而无需用户点击:

我自己没有测试过,但我猜Marker.showInfoWindow()会做的伎俩(假设Marker的可见性已经是true

为InfoWindow提供自定义视图

这里有两个选项,您应该参考GoogleMap.InfoWindowAdapter上的文档:

公共静态界面GoogleMap.InfoWindowAdapter

提供自定义呈现信息窗口的视图。

当显示标记的信息窗口时,无论原因(用户手势或对showInfoWindow()的程序性调用,都会调用此提供程序上的方法。由于任何时候只显示一个信息窗口,此提供程序可以选择重用视图,也可以选择在每个方法调用上创建新视图。

构造信息窗口时,将按定义的顺序调用此类中的方法。要替换默认信息窗口,请使用自定义渲染覆盖getInfoWindow(Marker)。要在缺省信息窗口框架(标注气泡)中仅替换信息窗口内容,请保留getInfoWindow(Marker)的默认实现,并覆盖getInfoContents(Marker)。

基本上,您是否覆盖getInfoWindow()getInfoContents()将取决于您是否只想自定义在标注气泡内看到的内容,或者您​​是否希望自定义整个信息窗口视图,包括标注气泡的替代方案。

一个警告:我相信当你重写这些方法时,它会执行一个简单的渲染,即在调用getInfoWindow()getInfoContents()时视图的样子。我自己有兴趣尝试复制本地Google Maps Android应用程序的外观,该应用程序在该地名旁边有一个“方向”图标。我相信的一个问题(见这里:https://stackoverflow.com/a/13713536/129475)是,如果你在视图中有类似按钮的东西,由于静态渲染,它可能不像按钮那样。


4
投票

自定义标记图像

您可以使用自定义标记图像(通常称为图标)替换默认标记图像。自定义图标始终设置为BitmapDescriptor,并使用BitmapDescriptorFactory类中的四种方法之一进行定义。

fromAsset(String assetName)使用assets目录中的图像创建自定义标记。

fromBitmap(位图图像​​)从位图图像创建自定义标记。

fromFile(String path)从指定路径的文件创建自定义图标。

fromResource(int resourceId)使用现有资源创建自定义标记。下面的代码段会创建一个带有自定义图标的标记。

 private static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
 private Marker melbourne = mMap.addMarker(new MarkerOptions()
                        .position(MELBOURNE)
                        .title("Melbourne")
                        .snippet("Population: 4,137,400")
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));

1
投票

这个简单的代码可以在不需要点击事件的情况下显示标题:

googleMap.addMarker(new MarkerOptions()
        .position(latLng)
        .title(String title))
        .showInfoWindow();

0
投票

为什么不保留标记数组呢?当涉及到标记时,迭代它们调用showInfoWindow()。可能不是最优雅的解决方案,但它符合我的想法。


0
投票

Google推出了IconGenerator类,可以轻松添加自定义图标。

IconGenerator iconGenerator = new IconGenerator(mContext);
Bitmap bitmap = iconGenerator.makeIcon("Text Of Icon");
mMap.addMarker(new MarkerOptions()
                      .position(latlng)
                      .title("Location")
                      .icon(BitmapDescriptorFactory.fromBitmap(bitmap)));

-5
投票

我用图片编辑器制作自己的标记解决了这个问题,下面有详细介绍。它需要一些时间才能完成,但它确实有效。

我使用Photoshop和53x110px标记。

© www.soinside.com 2019 - 2024. All rights reserved.