我正在尝试计算多行文本段落的宽度。据我所知,唯一可以在Android中执行此操作的类是StaticLayout(或DynamicLayout)类。当使用这个类时,我没有得到我的文本片段的正确长度,而是测量的尺寸有时更小,有时更大,取决于文本大小。
所以我基本上在寻找一种可靠地测量多行文本字符串宽度的方法。
下图显示了测量宽度与各种文字大小的实际文字长度的差异。
在自定义视图中运行以下代码创建屏幕截图:
@Override
protected void onDraw( Canvas canvas ) {
for( int i = 0; i < 15; i++ ) {
int startSize = 10;
int curSize = i + startSize;
paint.setTextSize( curSize );
String text = i + startSize + " - " + TEXT_SNIPPET;
layout = new StaticLayout( text,
paint,
Integer.MAX_VALUE,
Alignment.ALIGN_NORMAL,
1.0f,
0.0f,
true );
float top = STEP_DISTANCE * i;
float measuredWidth = layout.getLineMax( 0 );
canvas.drawRect( 0, top, measuredWidth, top + curSize, bgPaint );
canvas.drawText( text, 0, STEP_DISTANCE * i + curSize, paint );
}
}
答案 0 :(得分:1)
您可以尝试使用get text bounds。
private int calculateWidthFromFontSize(String testString, int currentSize)
{
Rect bounds = new Rect();
Paint paint = new Paint();
paint.setTextSize(currentSize);
paint.getTextBounds(testString, 0, testString.length(), bounds);
return (int) Math.ceil( bounds.width());
}
private int calculateHeightFromFontSize(String testString, int currentSize)
{
Rect bounds = new Rect();
Paint paint = new Paint();
paint.setTextSize(currentSize);
paint.getTextBounds(testString, 0, testString.length(), bounds);
return (int) Math.ceil( bounds.height());
}
答案 1 :(得分:1)
我有一个类似的问题,测量的文字宽度稍微偏离,一旦你将一个字体设置为油漆,它就会消失。
因此,在使用paint
中的StaticLayout
对象之前,只需设置字体:
textPaint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL))
或任何你想要的字体。
答案 2 :(得分:0)
这是一种可以获得任何文字长度的多行宽度的方法。 usableButtonWidth
可以是给定的文本空间。我使用usableButtonWidth
=按钮的宽度 - 填充。但是可以使用任何默认值。
使用StaticLayout,您可以获得usableButtonWidth
的文本高度。然后我尝试通过在循环中将其减少1px来减小可用宽度。如果高度增加,那么我们就会知道先前使用的宽度是允许的最大宽度。
将此值作为多行文字的宽度返回。
private int getTextWidth(){
if(this.getText().length() != 0){
Paint textPaint = new Paint();
Rect bounds = new Rect();
textPaint.setTextSize(this.getTextSize());
if(mTypeface != null){
textPaint.setTypeface(mTypeface);
}
String buttonText = this.getText().toString();
textPaint.getTextBounds(buttonText, 0, buttonText.length(), bounds);
if(bounds.width() > usableButtonWidth){
TextPaint longTextPaint = new TextPaint();
longTextPaint.setTextSize(this.getTextSize());
if(mTypeface != null){
longTextPaint.setTypeface(mTypeface);
}
StaticLayout staticLayout = new StaticLayout(this.getText(), longTextPaint, usableButtonWidth,
Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
int textLineCount = (int)Math.ceil(staticLayout.getHeight() / bounds.height());
int multiLineTextWidth = usableButtonWidth;
while ((int)Math.ceil(staticLayout.getHeight() / bounds.height()) == textLineCount && multiLineTextWidth > 1){
multiLineTextWidth--;
staticLayout = new StaticLayout(this.getText(), longTextPaint, multiLineTextWidth,
Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
return multiLineTextWidth+1;
} else {
return bounds.width();
}
} else {
return 0;
}
}