How to quickly get width and height of TextView using Paint.getTextBounds()?

android, java, performance, text-size, textview

Solution

Found a simple and not slow method of determining text width/height drawn with specific `Paint` that doesn't use `StaticLayout`.

public int getTextWidth(String text, Paint paint) {
    Rect bounds = new Rect();
    paint.getTextBounds(text, 0, text.length(), bounds);
    int width = bounds.left + bounds.width();
    return width;
}

public int getTextHeight(String text, Paint paint) {
    Rect bounds = new Rect();
    paint.getTextBounds(text, 0, text.length(), bounds);
    int height = bounds.bottom + bounds.height();
    return height;
}

The short simple description of trick: `Paint.getTextBounds(String text, int start, int end, Rect bounds)` returns `Rect` which doesn't starts at `(0,0)`. That is, to get actual width of text that will be set by calling `Canvas.drawText(String text, float x, float y, Paint paint)` with the same `Paint` object from `getTextBounds()` you should add the left position of `Rect`.

Notice this `bounds.left` - this the key of the problem.

In this way you will receive the same width of text, that you would receive using `Canvas.drawText()`.

Much more detailed explanation is given in this answer.

Problem

There is a method in Paint class: Paint.getTextBounds() which returns `Rect` occupied by some text. But according to this answer it returns something different then width/height of TextView. Q1: Is there a way to get width and height of TextView using `Rect` returned by Paint.getTextBounds()? Note, I do need to know width/height precisely. I will be happy to know upper bound of the `rect` with possible error about 2-3%, but it MUST be not greater (and should work for any phone not depending on screen resolution and pixel density) then TextView bounds Q2: Is there any other QUICK method of determining width and height of some text with specified textSize? I know, width can be determined by Paint.measureText(), but this doesn't return height. Height can be determined by creating new `StaticLayout` with text and then calling StaticLayout.getHeight(), but this is too slow. I need something more quicker. The background for all of this is making `AutoFitTextView` which will automaticaly fit text inside its bounds by up- or down-scaling text size, and it should do this quickly, as there will be many of such `AutoFitTextView`s changed dynamically very quickly.

Original source

Related problems