2012-06-01 39 views
13

我想計算一個多行文本段落的寬度。據我所知,唯一可以在Android中完成此功能的類是StaticLayout(或DynamicLayout)類。當使用這個類時,我沒有得到我的文本片段的適當長度,而是測量的尺寸有時更小,有時更大,這取決於文本大小。如何可靠地確定多行字符串的寬度?

所以我基本上尋找一種方法來可靠地測量多行文本字符串的寬度。

下圖顯示了測量寬度與實際文本長度在各種文本大小中的差異。 Diverging text and measure

的截圖創建運行在自定義查看下面的代碼:

@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); 
    } 
} 
+2

您是否試過'Paint.measureText()'? – neevek

+0

http://stackoverflow.com/questions/7549182/android-paint-measuretext-vs-gettextbounds – nullpotent

+0

@Neevek它會產生相同的結果,但最重要的是它無法測量多行文本。 – Moritz

回答

1

你可以嘗試使用獲取文本範圍。

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

我也有類似的問題,即測量文本寬度爲了一位,一旦你設置字樣的油漆會隨風而逝。 您使用的StaticLayoutpaint對象剛剛設置的字體所以之前:你想

textPaint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL)) 

或任何字樣。

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; 
    } 
} 
相關問題