Обтекание длинного текста на холсте Android - PullRequest
18 голосов
/ 25 февраля 2010

У меня есть пользовательский элемент управления, который выполняет много 2D-рисование прямо на canvas.

Часть этого рисунка является текстом, поэтому я использую метод Canvas.drawText().

Я хочу нарисовать текст в определенных пределах - верхний левый угол, определенная максимальная ширина и максимальное количество строк. После рисования текста я хочу знать, сколько строк это заняло.

Есть ли встроенная функция для рисования текста в границах, делающая разумное разбиение?

Если нет, есть ли стандартный рецепт для этого?

Ответы [ 3 ]

30 голосов
/ 26 февраля 2010

Для этого вы можете использовать класс android.text.StaticLayout; просто создайте StaticLayout для нужного текста, выравнивания, ширины и т. д. и вызовите его метод draw(Canvas) для рисования на холсте.

4 голосов
/ 25 июля 2012

Вы можете использовать Paint.getTextBounds () для измерения размера всей строки или Paint.getTextWidths (), чтобы получить ширину каждого символа. Затем разбейте строку соответствующим образом, прежде чем рисовать ее.

3 голосов
/ 14 августа 2015

У меня была такая же проблема. Одним из моих первых решений является следующее.

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

Чего не хватает:

  • Нет интеллектуального механизма разрыва, так как он разрывается на основе maxWidth

Как позвонить?

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

У меня есть статический класс CanvasUtils, в который я инкапсулирую подобные вещи. В основном я рисую текст в прямоугольнике. Это причина textHeight высота текста. Но вы можете передать то, что вы хотите, в функцию.

Хорошее программирование!

...