如何在 Android 的 MapView 上绘制带边框的文本?

Posted

技术标签:

【中文标题】如何在 Android 的 MapView 上绘制带边框的文本?【英文标题】:How do you draw text with a border on a MapView in Android? 【发布时间】:2010-12-15 23:33:42 【问题描述】:

我正在尝试在 android 上的 MapView 上绘制一些文本。文本的绘制很好,但是很难阅读文本,因为它是白色的,没有黑色边框(就像在 MapViews 上自然出现的用于表示城市、州和国家的文本的其余部分)。我似乎无法弄清楚如何用黑色边框绘制文本。有人知道怎么做吗?

这是我现在正在使用的那种代码(这只是示例代码,在我的一个叠加层中找到):

@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) 
    Paint textPaint = new Paint();
    textPaint.setARGB(255, 255, 255, 255);
    textPaint.setTextAlign(Paint.Align.CENTER);
    textPaint.setTextSize(16);
    textPaint.setTypeface(Typeface.DEFAULT_BOLD);

    canvas.drawText("Some Text", 100, 100, textPaint);

    super.draw(canvas, mapView, shadow);

【问题讨论】:

【参考方案1】:

最简单的方法是使用 Stroke... 像这样:

@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) 
    Paint strokePaint = new Paint();
    strokePaint.setARGB(255, 0, 0, 0);
    strokePaint.setTextAlign(Paint.Align.CENTER);
    strokePaint.setTextSize(16);
    strokePaint.setTypeface(Typeface.DEFAULT_BOLD);
    strokePaint.setStyle(Paint.Style.STROKE);
    strokePaint.setStrokeWidth(2);

    Paint textPaint = new Paint();
    textPaint.setARGB(255, 255, 255, 255);
    textPaint.setTextAlign(Paint.Align.CENTER);
    textPaint.setTextSize(16);
    textPaint.setTypeface(Typeface.DEFAULT_BOLD);

    canvas.drawText("Some Text", 100, 100, strokePaint);
    canvas.drawText("Some Text", 100, 100, textPaint);

    super.draw(canvas, mapView, shadow);

这将在文本外部绘制一个 2 像素的边框,然后在其顶部绘制文本,给您一个轮廓的错觉。

此外,可能值得在构造函数中设置画图,然后重用它们。

【讨论】:

啊,太好了!一个很好的解决方案。另外,我已经在构造函数中设置了油漆并重用;出于解释的目的,我只是简化了上面的示例。 我想(你看起来并不笨:))。主要是为了后代添加。 @fiXedd 但是我应该如何覆盖在 xml 文件中声明的视图? @Tom 你可以在 xml 中包含你自己的视图。而不是 你可以做 我会抛出一个 .setAntiAlias(true);每个 Paint 对象也是如此。【参考方案2】:

而不是这个代码(来自第一个答案)

canvas.drawText("Some Text", 100, 100, strokePaint);
canvas.drawText("Some Text", 100, 100, textPaint);

尝试使用相同的路径:

Path path = new Path();
String text = "Some Text";
textPaint.getTextPath(text, 0, text.length(), 0, 100, path);
canvas.drawPath(path, strokePaint);
canvas.drawPath(path, textPaint);

看起来更好?

【讨论】:

我不知道 getTextPath,这很酷! (虽然我不认为我会在这种特殊情况下使用它。) +1 因为这种绘制文本轮廓的替代方法是 bug that was introduced in Android 4.4 (KitKat) 的唯一有效解决方法,并且在 4.4.3 中仍然存在。 @Oleg您的回答早于引入错误,但您无意中挽救了我的理智。谢谢。 @Oleg 你应该告诉一些关于“tp”数据类型的信息......它是一个 Paint 对象。对我来说听起来很奇怪...... Paint 对象与文本和路径有什么关系? 这个解决方案肯定更好看! 当您调用tp.getTextPath() 时,变量tp 是什么?【参考方案3】:

一半的答案可能足够好也可能不够好(在我的情况下)是设置阴影:

textPaint.setShadowLayer(3, 0, 0, Color.BLACK);

阴影有助于文本突出很多,但不如黑色边框那么好。我仍然很好奇如何解决原来的问题。

【讨论】:

【参考方案4】:

这是在黑暗中拍摄的完整照片,可能有更好的方法,但如果您创建 4 个文本副本,将其颜色设置为黑色,然后将每个图层沿对角线移动 1 个像素,则会产生一种错觉边框。因此,如果您的文本定位在 [100,100],则需要将 4 个阴影定位在 [99,99]、[99,101]、[101,99] 和 [101,101],如下所示:

canvas.drawText("Some Text", 99, 99, borderPaint);
canvas.drawText("Some Text", 99, 101, borderPaint);
canvas.drawText("Some Text", 101, 99, borderPaint);
canvas.drawText("Some Text", 101, 101, borderPaint);

canvas.drawText("Some Text", 100, 100, textPaint);

【讨论】:

这既绝妙又荒谬……我得试试看。 :) 我经常在 gimp 中使用这种技术(不知道如何正确使用)

以上是关于如何在 Android 的 MapView 上绘制带边框的文本?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MapView 中绘制显示行车方向的箭头?

如何在不连接它们的情况下在 MapView 上绘制两个 MKPolygons?

如何在 MapView 上绘制多边形,填充它,并在其上放置一个 onTouch 事件

Android Mapview可绘制图标毁容

在 MapView 上绘制 MKPolyline 显示两个位置之间的直线

如何自动缩放mapView以显示覆盖