2012-06-01 7 views
13

Sto provando a calcolare la larghezza di un paragrafo di testo multilinea. Per quanto ne so, l'unica classe che può farlo in Android è la classe StaticLayout (o DynamicLayout). Quando uso questa classe non ottengo la lunghezza corretta del mio frammento di testo, ma piuttosto le dimensioni misurate sono a volte più piccole e talvolta maggiori a seconda delle dimensioni del testo.Come determinare in modo affidabile la larghezza di una stringa multi linea?

Quindi sono fondamentalmente alla ricerca di un modo per misurare in modo affidabile la larghezza di una stringa di testo multilinea.

L'immagine seguente mostra come la larghezza misurata diverge dalla lunghezza effettiva del testo in varie dimensioni del testo. Diverging text and measure

La schermata viene creato in esecuzione il codice seguente in una visualizzazione personalizzata:

@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

Hai provato 'Paint.measureText()'? – neevek

+0

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

+0

@Neevek produce lo stesso risultato, ma in cima non è in grado di misurare il testo su più righe. – Moritz

risposta

1

Si potrebbe provare a utilizzare i limiti di testo get.

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

ho avuto un problema simile in cui la larghezza del testo misurata era fuori da un po ', una volta impostato un carattere tipografico alla vernice questo andrà via. Quindi, prima di utilizzare l'oggetto paint nella StaticLayout basta impostare il tipo di carattere:

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

o qualsiasi tipo di carattere che si desidera.

0

Ecco un modo in cui è possibile ottenere la larghezza su più righe di qualsiasi lunghezza del testo. usableButtonWidth può essere un determinato spazio di testo. Ho usato usableButtonWidth = larghezza del pulsante - padding. Ma qualsiasi valore predefinito può essere utilizzato.

Utilizzando StaticLayout, è possibile ottenere l'altezza del testo per usableButtonWidth. Quindi provo solo a ridurre la larghezza disponibile diminuendola di 1px in un ciclo. Se l'altezza aumenta, veniamo a sapere che la larghezza precedentemente utilizzata era la massima consentita.

Restituisce questo valore come larghezza del testo multilinea.

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; 
    } 
} 
Problemi correlati