Android MapView自定义标记都是一样大小的

标签 android android-mapview google-maps-markers itemizedoverlay

我正在编写一个应用程序,它会显示一张带有一堆标记的 map 。我希望标记是动态的(在其上显示动态内容)。因为标记内容是动态的,所以每个标记的大小都不同。

我在文档中发现“可以为不同的状态返回不同的标记。不同的标记可以有不同的边界。”这里:https://developers.google.com/maps/documentation/android/reference/com/google/android/maps/OverlayItem#getMarker(int)

我假设这意味着同一叠加层上的多个标记可以有不同的大小。对吗?

我的叠加层上有一个 ArrayList(扩展了 BalloonItemizedOverlay)。叠加层的 createItem() 方法如下所示:

@Override
protected OverlayItem createItem(final int index)
{
    final Person person = people.get(index);
    final GeoPoint gp = new GeoPoint(person.getLat(), person.getLng());

    final OverlayItem oi = new OverlayItem(gp, person.getName(), person.getName());
    oi.setMarker(new PersonDrawable(defaultMarker, person));

    return oi;
}

然后在我的 PersonDrawable 中有一个 drawable,它有一个 9 patch 作为背景图像,然后在它上面绘制文本:

public PersonDrawable(final Drawable iBackground, final Person person)
{
    background = iBackground;
    text = person.getName();
    padding = new Rect();

    if (background instanceof NinePatchDrawable)
    {
        // This is getting hit, and just sets the value of the padding
        final NinePatchDrawable ninePatch = (NinePatchDrawable) background;
        ninePatch.getPadding(padding);
    }

    // set the bounds of the marker
    bounds = background.getBounds();

    paint = new Paint();
    paint.setColor(Color.rgb(255, 255, 255));
    paint.setFakeBoldText(true);
    paint.setTextSize(30);

    // find the bounds of the text
    final Rect textBounds = new Rect();
    paint.getTextBounds(text, 0, text.length(), textBounds);

    // set the left and right bounds to that of the text plus the padding (then center it)
    bounds.left = 0 - (textBounds.width() / 2) - padding.left;
    bounds.right = 0 + (textBounds.width() / 2) + padding.right;

    // set the bounds of the drawable
    setBounds(bounds);
}

@Override
public void draw(final Canvas canvas)
{
    // when it's time to draw, draw the background
    background.draw(canvas);
    // then draw the text within the padding
    canvas.drawText(text, bounds.left + padding.left, bounds.bottom - padding.bottom, paint);
}

每个标记都有一个不同的边界集,即使在它被绘制在叠加层上之后,它的边界也是不同的。 MapView(或 Overlay)没有重用 createItem() 中的对象。然而,Overlay 似乎总是选择一个标记并假定这是所有标记的大小。这只是行为吗?我可以做些什么来让它以不同方式尊重每个标记的边界吗?

这里有一些图片,当它决定选择一个更大的标记时,结果没问题:

Wolverine is longer so things look alright

但是当它选择使用较小的标记作为尺寸时:

Beast is a little shorter and overflow

最佳答案

问题在于,当从资源中加载Drawable 时,它被视为可共享资源。来自 Drawable 文档:

By default, all drawables instances loaded from the same resource share a common state; if you modify the state of one instance, all the other instances will receive the same modification.

OverlayItem 中,假设 Drawable 始终具有相同的大小。您看到的效果是对 Drawable 的最后修改覆盖了所有以前的修改,因此 Drawable 的所有显示都显示完全相同。

解决方案是防止共享 Drawable 的修改。您可以使用 mutate() 方法结合从资源中多次加载 Drawable 来执行此操作。您应该结合上面概述的 PersonDrawable 构造函数来执行此操作。

关于Android MapView自定义标记都是一样大小的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13197725/

相关文章:

java - 一些数据库逻辑,检索正确的条目

Android NDK GCC 似乎是 clang - 它应该是这样吗?

java - Android MediaPlayer 运行时错误

android map View 不工作

javascript - 对于谷歌地图标记,是否可以在 svg 中包含多种颜色

android - 发布了未知的位图引用

android - 如何使用 facebook api 在 facebook 帖子中设置图标?

android - 将mapview添加到android中的选项卡中

android - 在多层android google maps中传播事件

javascript - 使用 ASPNET MVC 3 和 Razor 在单独的 javascript 文件中@Url.Content