Android:在画布上测量文本高度

时间:2012-02-20 16:22:21

标签: android paint android-canvas

我目前正致力于渲染Bitmap,然后我想将其发送到移动打印机。但是,我正在努力测量文本的高度,所以我可以适当地提高y位置。

我的基本位图/画布/颜料配置是这样的(字体大小是16,位图的尺寸是200x400(宽x高):

public MyRenderer() {
    // Initialize bitmap
    bitmap = Bitmap.createBitmap(200, 400, Bitmap.Config.ARGB_8888);

    // Initialize canvas
    canvas = new Canvas(bitmap);

    // Initialize brush (Paint instance)
    brush = new Paint();
    brush.setTextSize(16);
    brush.setTypeface(Typeface.SANS_SERIF);
    brush.setColor(Color.BLACK);
    brush.setStyle(Paint.Style.FILL);
    brush.setAntiAlias(true);
    brush.setTextAlign(Align.LEFT);
}

到目前为止一切顺利,现在我要做的是:如果我使用Paint的方法drawText,我需要提供x和y坐标。至于x为零(假设左对齐文本)但是对于y,我必须计算我打印的每个文本的高度并将其加起来,这样我就可以跟踪我当前的y位置。

这就是奇怪的地方:我使用以下方法来确定文本的高度(使用我先前初始化的Paint对象 - 它叫做“brush”):

public int measureHeight(String text) {
    Rect result = new Rect();
    // Measure the text rectangle to get the height
    brush.getTextBounds(text, 0, text.length(), result);
    return result.height();
}

以上方法为以下文本返回以下值:

  1. Hello World ”返回高度 12
  2. 相机实例可用于计算3D变换并生成矩阵。”返回高度 16
  3. 介绍Android设计:了解创建世界级Android用户界面的原则,构建模块和模式的地方。无论您是UI专业人士还是扮演该角色的开发人员,这些文档都会向您展示如何做出好的设计决策,无论大小。“返回高度 16
  4. 对我而言,数字2和3返回的高度比数字1高,但是如果一条线的高度为12(正如数字1那样) - 没有意义,多条线的高度为16 ?

    我在这里遗漏了什么吗?有一种方便的方法来测量文本的宽度(使用paint的实例和调用measureText(“myText”),它完美地工作,但是当涉及到高度时,我很茫然,如上面给出的结果对我没有任何意义。

    修改

    我知道,getTextBounds可能不会自动包装多行文本,这没关系,我已经写了一个分割文本的方法,但即使它只测量一行,上面给出的长度值仍然看起来不可能的。

2 个答案:

答案 0 :(得分:16)

我认为这是因为“计算”中的“p”延伸到基线以下,而“Hello World”仅包含高于基线的字母。

由于行距离不应取决于您的文字恰好包含哪些特定字母,因此您可能正在寻找可以通过Paint.FontMetrics获取的Paint.getFontMetrics()。计算descent - ascent + leading以获得建议的基线距离(因为上升具有负值)。

答案 1 :(得分:4)

接受的答案中有一个小错误。如果您想要文本高度,则应使用

Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float textHeight = fm.descent - fm.ascent;

如果你想要高度,你应该使用

float lineHeight = fm.bottom - fm.top + fm.leading;

前导是可选的行间距,因此如果您需要获得行高,则可以包含它。但如果您只想要文本高度,那么您可以将其关闭。

注意

  • 我从来没有真正看到leading是除了0之外的任何其他东西,据我所知,它甚至似乎在TextView source code中被忽略了(及其相关联) LayoutStaticLayout等)。如果我错了,请纠正我。所以它可能是安全的,因为它使得它不能用于高效率,但我对此并不完全确定。

另见