2010-02-25 13 views
18

Ho un controllo personalizzato che esegue molto disegno 2D direttamente sullo canvas.Avvolgere testo lungo su una tela Android

Parte di questo disegno è testo, quindi sto utilizzando il metodo Canvas.drawText().

Desidero disegnare il testo entro alcuni limiti: una larghezza massima in alto a sinistra, una larghezza massima e un numero massimo di linee. Dopo aver disegnato il testo, voglio sapere quante righe ci sono volute.

Esiste una funzione incorporata per disegnare il testo entro i limiti della divisione in modo sensato?

In caso contrario, esiste una ricetta standard per farlo?

+0

Vedere questa risposta per un buon esempio di utilizzo di 'StaticLayout's: http://stackoverflow.com/a/8369690/293280 –

risposta

30

È possibile utilizzare la classe android.text.StaticLayout per questo; crea semplicemente un StaticLayout per il testo, l'allineamento, la larghezza, ecc. desiderato e chiama il suo metodo draw(Canvas) per disegnare sulla tela.

+0

Incredibile che l'ho trascurato – Will

+0

È solo per Android? Che dire delle altre piattaforme? –

+0

Grande! Come centreresti il ​​testo sulla tela? –

4

È possibile utilizzare Paint.getTextBounds() per misurare la dimensione dell'intera stringa o Paint.getTextWidths() per ottenere la larghezza di ciascun carattere. Quindi dividere la stringa in modo appropriato prima di disegnarla.

3

Ho avuto lo stesso problema. Una delle mie prime soluzioni sta seguendo.

/** 
    * This function draws the text on the canvas based on the x-, y-position. 
    * If it has to break it into lines it will do it based on the max width 
    * provided. 
    * 
    * @author Alessandro Giusa 
    * @version 0.1, 14.08.2015 
    * @param canvas 
    *   canvas to draw on 
    * @param paint 
    *   paint object 
    * @param x 
    *   x position to draw on canvas 
    * @param y 
    *   start y-position to draw the text. 
    * @param maxWidth 
    *   maximal width for break line calculation 
    * @param text 
    *   text to draw 
    */ 
public static void drawTextAndBreakLine(final Canvas canvas, final Paint paint, 
     final float x, final float y, final float maxWidth, final String text) { 
    String textToDisplay = text; 
    String tempText = ""; 
    char[] chars; 
    float textHeight = paint.descent() - paint.ascent(); 
    float lastY = y; 
    int nextPos = 0; 
    int lengthBeforeBreak = textToDisplay.length(); 
    do { 
     lengthBeforeBreak = textToDisplay.length(); 
     chars = textToDisplay.toCharArray(); 
     nextPos = paint.breakText(chars, 0, chars.length, maxWidth, null); 
     tempText = textToDisplay.substring(0, nextPos); 
     textToDisplay = textToDisplay.substring(nextPos, textToDisplay.length()); 
     canvas.drawText(tempText, x, lastY, paint); 
     lastY += textHeight; 
    } while(nextPos < lengthBeforeBreak); 
} 

Quello che manca:

  • Nessun meccanismo di interruzione linea intelligente, dal momento che rompe basa sul maxwidth

Come chiamare?

paint.setTextSize(40); 
    paint.setColor(Color.WHITE); 
    paint.setSubpixelText(true); 
    float textHeight = paint.descent() - paint.ascent(); 
    CanvasUtils.drawTextAndBreakLine(canvas, paint, this.left, 
      textHeight, this.displayWidth, this.text); 

Ho una classe statica chiamata CanvasUtils in cui incapsulo cose del genere. Fondamentalmente disegno il testo all'interno di un rettangolo. Questo è il motivo textHeight è l'altezza del testo. Ma puoi passare ciò che vuoi alla funzione.

Buona programmazione!

+0

Sì, questo ha funzionato per me, ma costringe le parole a rompere! C'è un modo per risolvere questo? – Eenvincible

+0

Hey Eenvincible, vuoi dire singole parole? Sillabazione? –

+0

Non in particolare. ciò che accade con questo codice è che il testo si avvolge correttamente all'interno del rettangolo, ma alcune parole vengono troncate finendo per scomporre in nuove linee con parte delle parole che mostrano in una riga e parte di essa nella riga successiva. – Eenvincible