有没有直接测量文本高度的方法?我现在的方法是使用Paint的measureText()
来获得宽度,然后通过反复试验找到一个值来获得大致的高度。我也一直在摆弄FontMetrics
,但所有这些看起来都像是糟糕的近似方法。
我正在试着根据不同的分辨率来缩放东西。我可以做到这一点,但我最终得到了令人难以置信的冗长的代码,需要大量的计算来确定相对大小。我最讨厌这个了!一定有更好的方法。
发布于 2010-09-27 23:02:02
paint.getTextBounds() (对象方法)怎么样?
发布于 2017-02-07 21:58:40
根据你的需要,有不同的方法来测量高度。
如果您正在执行诸如精确地将少量固定文本居中之类的操作,那么您可能需要getTextBounds
。您可以像这样获得边界矩形
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
int height = bounds.height();
如下图所示,不同的字符串将提供不同的高度(以红色显示)。
在某些情况下,这些不同的高度可能是一个缺点,因为无论文本是什么,您只需要一个恒定的高度。请参阅下一节。
您可以根据字体度量计算字体的高度。高度始终是相同的,因为它是从字体获得的,而不是任何特定的文本字符串。
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float height = fm.descent - fm.ascent;
基线是文本所在的行。下降通常是字符在线下的最远距离,上升通常是字符在线上的最远距离。为了得到高度,你必须减去上升,因为它是一个负值。(基线是y=0
,y
会在屏幕上减少折痕。)
请看下图。这两个字符串的高度都是234.375
。
如果您想要行高而不仅仅是文本高度,可以执行以下操作:
float height = fm.bottom - fm.top + fm.leading; // 265.4297
这些是行的bottom
和top
。行距(行间间距)通常为零,但无论如何都应该添加它。
上面的图片来自this project。您可以试用它来了解Font Metrics是如何工作的。
要测量多行文字的高度,应使用StaticLayout
。我在this answer中谈到了一些细节,但获得这个高度的基本方法如下:
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();
发布于 2012-08-02 15:02:07
@bramp的答案是正确的-部分是因为它没有提到计算出的边界将是包含全部文本的最小矩形,并且隐式起始坐标为0,0。
这意味着,例如"Py“的高度将不同于"py”或"hi“或"oi”或"aw“的高度,因为它们在像素方面需要不同的高度。
这绝不等同于经典java中的FontMetrics。
虽然文本的宽度不是一个很大的问题,但高度却是一个很大的问题。
特别是,如果您需要垂直居中对齐绘制的文本,请尝试获取文本"a“的边界(不带引号),而不是使用要绘制的文本。对我来说很有效。
我的意思是:
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”),我们就可以在其余文本中重用它的对齐方式。这将居中对齐所有文本以及基线对齐它们。
https://stackoverflow.com/questions/3654321
复制相似问题