Wrapping long text on an Android Canvas

后端 未结 3 1639
半阙折子戏
半阙折子戏 2020-12-15 18:30

I have a custom control that is doing a lot of 2D drawing straight to the canvas.

Some of this drawing is text, so I am using the Canvas.drawText() meth

相关标签:
3条回答
  • 2020-12-15 19:12

    You can use the android.text.StaticLayout class for this; simply create a StaticLayout for the desired text, alignment, width, etc. and call its draw(Canvas) method to draw to the canvas.

    0 讨论(0)
  • 2020-12-15 19:13

    You can use Paint.getTextBounds() to measure the size of the entire string or Paint.getTextWidths() to get the width of each character. Then split the string appropriately before drawing it.

    0 讨论(0)
  • 2020-12-15 19:22

    I had the same problem. One of my first solution is following.

    /**
         * 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);
    }
    

    What is missing:

    • No intelligent break-line mechanism, since it breaks based on the maxWidth

    How to call?

        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);
    

    I have a static class called CanvasUtils where I encapsulate stuff like this. Basically I draw the text within a rectangle. This is the reason textHeight is the height of the text. But you can pass what you want to the function.

    Good programming!

    0 讨论(0)
提交回复
热议问题