Any straight forward way to measure the height of text?
The way I am doing it now is by using Paint's measureText()
to get the width, then by trial and error finding a value to get an approximate height. I've also been messing around with FontMetrics
, but all these seem like approximate methods that suck.
I am trying to scale things for different resolutions. I can do it, but I end up with incredibly verbose code with lots of calculations to determine relative sizes. I hate it! There has to be a better way.
There are different ways to measure the height depending on what you need.
If you are doing something like precisely centering a small amount of fixed text, you probably want getTextBounds
. You can get the bounding rectangle like this
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
int height = bounds.height();
As you can see for the following images, different strings will give different heights (shown in red).
These differing heights could be a disadvantage in some situations when you just need a constant height no matter what the text is. See the next section.
You can calculate the hight of the font from the font metrics. The height is always the same because it is obtained from the font, not any particular text string.
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float height = fm.descent - fm.ascent;
The baseline is the line that the text sits on. The descent is generally the furthest a character will go below the line and the ascent is generally the furthest a character will go above the line. To get the height you have to subtract ascent because it is a negative value. (The baseline is y=0
and y
descreases up the screen.)
Look at the following image. The heights for both of the strings are 234.375
.
If you want the line height rather than just the text height, you could do the following:
float height = fm.bottom - fm.top + fm.leading; // 265.4297
These are the bottom
and top
of the line. The leading (interline spacing) is usually zero, but you should add it anyway.
The images above come from this project. You can play around with it to see how Font Metrics work.
For measuring the height of multi-line text you should use a StaticLayout
. I talked about it in some detail in this answer, but the basic way to get this height is like this:
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();