我有一个textview,在根布局下宽度为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
。当scren宽度本身为480
时,为什么将宽度打印为10278?如果它假设它是一条线并计算那么getTextBounds
的重点是什么。
答案 0 :(得分:1)
getTextBounds不会返回视图的大小,而是显示您提供给它的完整字符串所需的最小空间:
返回边界(由调用者分配)包含所有字符的最小矩形,隐含的原点位于(0,0)。
这意味着对于1000个字符,并且在Paint
对象中给定当前配置的字体,它将需要至少10278个像素才能打印它们。您的文本或Paint
对象来自textView。
答案 1 :(得分:1)
文档说明int end是" 1超过要测量的字符串中的最后一个字符。" http://developer.android.com/reference/android/graphics/Paint.html#getTextBounds(java.lang.String,int,int,android.graphics.Rect)
你应该:
textView.getPaint().getTextBounds(text, 0, text.length(), rect);
这也适用于Canvas.drawText()。
显示文本的TextView将是"包装"文本。 getTextBounds方法根本不知道TextView。
事实上,如果您要构建自己的自定义View来显示文本,那么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);
符合我的要求:)