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

时间:2012-12-07 12:56:30

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

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

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

9 个答案:

答案 0 :(得分:82)

我也偶然发现了这个问题。 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旋转功能。

答案 1 :(得分:47)

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

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

答案 2 :(得分:15)

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

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

它有:

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

热图 - 将大量点显示为热图

IconGenerator - 在Markers上显示文字(见截图)

Markers made using the library

非常重要的是,它可以修改任何线程,因此处理许多标记非常简单

答案 3 :(得分:9)

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

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

我自己没有对此进行测试,但我猜测Marker.showInfoWindow()可以解决问题(假设Marker的可见性已经true

为InfoWindow提供自定义视图

此处有两个选项,您应参阅GoogleMap.InfoWindowAdapter上的文档:

  

公共静态界面GoogleMap.InfoWindowAdapter

     

提供视图   定制的信息窗口渲染。

     

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

     

构造信息窗口时,会调用此类中的方法   定义的订单。要替换默认信息窗口,请覆盖   使用自定义渲染获取getInfoWindow(Marker)。要只替换   信息窗口内容,在默认信息窗口框架内(   callout bubble),保留默认实现   getInfoWindow(Marker)到位并覆盖getInfoContents(Marker)   代替。

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

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

答案 4 :(得分: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)));

答案 5 :(得分:1)

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

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

答案 6 :(得分:0)

为什么不保留一系列标记,然后在标记标记时,通过调用showInfoWindow()进行迭代。可能不是最优雅的解决方案,但它符合我的想法。

答案 7 :(得分:0)

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

to go
  ask turtles [
    direzione-turtles
    face direzione ;aggiunto
    ifelse  next-patch != nobody
    [
      face next-patch
      fd 1 ask patch-here [set done? true]]
    [set other-choices neighbors with [strada > 0 and stato <= 4 ]
      move-to one-of other-choices ;al posto di face
      fd 1]]
  tick
end

to-report next-patch
  if direzione = casa and (member? patch-here [neighbors] of casa) [
    set direzione ufficio
  ]
  if direzione = ufficio and (member? patch-here [neighbors] of ufficio) [
    set direzione casa
  ]
  set choices neighbors with [done? = false and strada > 0 and stato >= 1 and stato <= 4]
  set choice min-one-of choices [distance [direzione] of myself]
  report choice
end

答案 8 :(得分:-5)

我通过使用下面有详细信息的图片编辑器制作我自己的标记来解决这个问题。这需要一些时间,但它确实有效。

我使用了Photoshop和53x110px标记。

an example marker that I made