首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >测量要在画布上绘制的文本高度( Android )

测量要在画布上绘制的文本高度( Android )
EN

Stack Overflow用户
提问于 2010-09-07 05:12:11
回答 8查看 109.7K关注 0票数 146

有没有直接测量文本高度的方法?我现在的方法是使用Paint的measureText()来获得宽度,然后通过反复试验找到一个值来获得大致的高度。我也一直在摆弄FontMetrics,但所有这些看起来都像是糟糕的近似方法。

我正在试着根据不同的分辨率来缩放东西。我可以做到这一点,但我最终得到了令人难以置信的冗长的代码,需要大量的计算来确定相对大小。我最讨厌这个了!一定有更好的方法。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-09-27 23:02:02

paint.getTextBounds() (对象方法)怎么样?

票数 146
EN

Stack Overflow用户

发布于 2017-02-07 21:58:40

根据你的需要,有不同的方法来测量高度。

getTextBounds

如果您正在执行诸如精确地将少量固定文本居中之类的操作,那么您可能需要getTextBounds。您可以像这样获得边界矩形

代码语言:javascript
复制
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
int height = bounds.height();

如下图所示,不同的字符串将提供不同的高度(以红色显示)。

在某些情况下,这些不同的高度可能是一个缺点,因为无论文本是什么,您只需要一个恒定的高度。请参阅下一节。

Paint.FontMetrics

您可以根据字体度量计算字体的高度。高度始终是相同的,因为它是从字体获得的,而不是任何特定的文本字符串。

代码语言:javascript
复制
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float height = fm.descent - fm.ascent;

基线是文本所在的行。下降通常是字符在线下的最远距离,上升通常是字符在线上的最远距离。为了得到高度,你必须减去上升,因为它是一个负值。(基线是y=0y会在屏幕上减少折痕。)

请看下图。这两个字符串的高度都是234.375

如果您想要行高而不仅仅是文本高度,可以执行以下操作:

代码语言:javascript
复制
float height = fm.bottom - fm.top + fm.leading; // 265.4297

这些是行的bottomtop。行距(行间间距)通常为零,但无论如何都应该添加它。

上面的图片来自this project。您可以试用它来了解Font Metrics是如何工作的。

StaticLayout

要测量多行文字的高度,应使用StaticLayout。我在this answer中谈到了一些细节,但获得这个高度的基本方法如下:

代码语言:javascript
复制
String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";

TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);

int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;

StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);

float height = myStaticLayout.getHeight(); 
票数 264
EN

Stack Overflow用户

发布于 2012-08-02 15:02:07

@bramp的答案是正确的-部分是因为它没有提到计算出的边界将是包含全部文本的最小矩形,并且隐式起始坐标为0,0。

这意味着,例如"Py“的高度将不同于"py”或"hi“或"oi”或"aw“的高度,因为它们在像素方面需要不同的高度。

这绝不等同于经典java中的FontMetrics。

虽然文本的宽度不是一个很大的问题,但高度却是一个很大的问题。

特别是,如果您需要垂直居中对齐绘制的文本,请尝试获取文本"a“的边界(不带引号),而不是使用要绘制的文本。对我来说很有效。

我的意思是:

代码语言:javascript
复制
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);

paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(textSize);

Rect bounds = new Rect();
paint.getTextBounds("a", 0, 1, bounds);

buffer.drawText(this.myText, canvasWidth >> 1, (canvasHeight + bounds.height()) >> 1, paint);
// remember x >> 1 is equivalent to x / 2, but works much much faster

垂直居中对齐文本意味着垂直居中对齐边界矩形-这对于不同的文本(大写字母、长字母等)是不同的。但我们实际上想要做的是对齐渲染文本的基线,使它们看起来不会升高或有凹槽。因此,只要我们知道最小字母的中心(例如“a”),我们就可以在其余文本中重用它的对齐方式。这将居中对齐所有文本以及基线对齐它们。

票数 89
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3654321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档