Android : Paint.getTextBounds returns 宽度比屏幕宽度大很多

Android : Paint.getTextBounds returns width much greater than the width of the screen

我在根布局下有一个宽度为 fill_parent 的文本视图,这意味着它的屏幕宽度为 480
我正在尝试在文本视图中测量此文本的边界。所以我这样做了:

Rect rect = new Rect();
textView.getPaint().getTextBounds(text,0,text.length()-1,rect);
Log.v(TAG,"Width : Height ="+rect.width()+" : "+width.height());

但它打印 10278 : 79。当屏幕宽度本身为 480 时,为什么将宽度打印为 10278?如果它假设它是单行并计算那么 getTextBounds 有什么意义。

getTextBounds 不是 return 视图的大小,而是显示您提供给它的完整字符串所需的最小 space:

Return in bounds (allocated by the caller) the smallest rectangle that encloses all of the characters, with an implied origin at (0,0).

这意味着对于您的 1000 个字符,并且考虑到 Paint 对象中当前配置的字体,打印它们至少需要 10278 像素。您的文本或 Paint 对象来自 textView 并不重要。

文档指出 int end 是“要测量的字符串中最后一个字符后的 1”。 http://developer.android.com/reference/android/graphics/Paint.html#getTextBounds(java.lang.String, 整数, 整数, android.graphics.Rect)

你应该有:

textView.getPaint().getTextBounds(text, 0, text.length(), rect);

这也适用于 Canvas.drawText()。

显示文本的 TextView 将是 "wrapping" 文本。 getTextBounds 方法根本不知道 TextView。

事实上,如果您要构建自己的自定义视图来显示文本,getTextBounds 将对实现您自己的文本换行非常有用。下面的代码表现得很糟糕,但是迭代了一个字符串,将它的部分绘制到 Canvas,有效地包装了文本。

    private void drawText(Canvas canvas) {

        String text = "Nunc eleifend erat eu nulla varius iaculis. Quisque feugiat justo sit amet" +
                " neque interdum tempor. Curabitur faucibus facilisis tristique. Donec posuere" +
                " viverra magna, eu accumsan sapien congue id. Cras fringilla justo ut lacus" +
                " molestie, et venenatis orci egestas. Vivamus pretium, nisl quis cursus cursus," +
                " dolor eros porta neque, sit amet viverra ante orci non elit. Donec odio neque," +
                " volutpat sit amet dui sit amet, fringilla tempus sapien. Donec sed mollis justo." +
                " In dignissim tincidunt neque, eu luctus justo egestas nec. Donec commodo ut arcu" +
                " vel placerat. Donec ullamcorper justo eget justo commodo hendrerit. Quisque" +
                " commodo imperdiet posuere. Aenean vehicula dui.";

        Paint paint = new Paint();
        paint.setTextSize(30);
        paint.setAntiAlias(true);

        int padding = 20;

        int availWidth = getWidth() - 2 * padding;
        int availHeight = getHeight() - 2 * padding;

        Rect bounds = new Rect();
        int currentTextBottom = 0;
        int firstCharInLine = 0;
        int lastCharInLine = 0;

        outerLoop: while (currentTextBottom < availHeight) {

            while (Character.isWhitespace(text.charAt(firstCharInLine))) {
                lastCharInLine = ++firstCharInLine;
            }

            for (int i = firstCharInLine + 1; i < text.length(); i++) {
                paint.getTextBounds(text, firstCharInLine, i, bounds);

                if (bounds.width() <= availWidth) {
                    if (Character.isWhitespace(text.charAt(i))) {
                        lastCharInLine = i;
                    }
                } else {
                    currentTextBottom += bounds.height();
                    if (firstCharInLine == lastCharInLine) {
                        lastCharInLine = i;
                    }
                    canvas.drawText(text, firstCharInLine, lastCharInLine, padding, currentTextBottom + padding, paint);
                    firstCharInLine = lastCharInLine++;
                    break;
                }
                if (i == text.length() - 1) {
                    currentTextBottom += bounds.height();
                    lastCharInLine = text.length();
                    canvas.drawText(text, firstCharInLine, lastCharInLine, padding, currentTextBottom + padding, paint);
                    break outerLoop;
                }
            }
        }
    }
}

编辑 - 作为旁注,我刚刚注意到 bounds.width() 和 Paint.measureText() 之间的区别!与上述代码完全无关,我遇到了 Paint.Align.Center 故障问题并且并不总是按预期工作。所以我删除了任何文本对齐并尝试:

canvas.drawText(
        text,
        viewWidth / 2f - bounds.width() / 2f,
        viewHeight / 2f + bounds.height() / 2f,
        paint);

但这并没有正确地水平对齐。当我这样做时:

float textWidth = paint.measureText(text);
canvas.drawText(
        text,
        viewWidth / 2f - textWidth / 2,
        viewHeight / 2f + bounds.height() / 2f,
        paint);

它符合我的满意度:)