Android – Drawing multiline text on canvas

If you always wanted to know how to draw multiline text on canvas you came to the right place. Meet StaticLayout, your new best friend when it comes to drawing text on canvas.

I stumbled upon this class while developing a custom Watch Face for Android Wear. When it comes to Android Wear you’re dealing with very small canvas and you have to think how and where your text will be placed. Drawing multiline text is actually pretty simple and this is what you need to do:

1. Initialize Paint object. Use TextPaint which is an extension of Paint.

//Set your own color, size etc.
TextPaint textPaint = new TextPaint();

2. onDraw method is the place where the fun things happen.

@Override 
public void onDraw (Canvas canvas, Rect bounds) { 
    super.onDraw(canvas, bounds);

    String textOnCanvas = "I registered koc.sexy so that my package 
         name can start with sexy.koc";

    //Static layout which will be drawn on canvas
    //textOnCanvas - text which will be drawn
    //text paint - paint object
    //bounds.width - width of the layout
    //Layout.Alignment.ALIGN_CENTER - layout alignment
    //1 - text spacing multiply
    //1 - text spacing add
    //true - include padding
    StaticLayout sl = new StaticLayout(textOnCanvas, textPaint, bounds.width(),
           Layout.Alignment.ALIGN_CENTER, 1, 1, true);

    canvas.save();

    //calculate X and Y coordinates - In this case we want to draw the text in the 
    //center of canvas so we calculate
    //text height and number of lines to move Y coordinate to center.
    float textHeight = getTextHeight(textOnCanvas, textPaint);
    int numberOfTextLines = sl.getLineCount();
    float textYCoordinate = bounds.exactCenterY() - 
         ((numberOfTextLines * textHeight) / 2);

    //text will be drawn from left
    float textXCoordinate = bounds.left;

    canvas.translate(textXCoordinate, textYCoordinate);

    //draws static layout on canvas
    sl.draw(canvas);
    canvas.restore();
 
} 

/**
 * @return text height
 */
private float getTextHeight(String text, Paint paint) {

    Rect rect = new Rect();
    paint.getTextBounds(text, 0, text.length(), rect);
    return rect.height();
}

And this is how the text will look like:

Multiline text on canvas

If your text is going to change you can use DynamicLayout which updates itself as the text is edited

Although this example is done on Watch Face canvas, you can also use StaticLayout when developing mobile applications.