холст drawtext с многострочным

Я разрабатываю приложение для комментирования изображений. Я рисую текст на холсте с помощью canvas.drawText(text, x, y, imgPaint);

Это появляется в одной строке. Мне нужно разбить строку на многострочную, когда текст пересекает ширину холста

заранее спасибо


person varghesekutty    schedule 24.02.2015    source источник


Ответы (3)


Вам нужно использовать StaticLayout:

TextPaint mTextPaint=new TextPaint();
StaticLayout mTextLayout = new StaticLayout("my text\nNext line is very long text that does not definitely fit in a single line on an android device. This will show you how!", mTextPaint, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

canvas.save();
// calculate x and y position where your text will be placed

textX = 100;
textY = 100;

canvas.translate(textX, textY);
mTextLayout.draw(canvas);
canvas.restore();
person Kasra    schedule 24.02.2015
comment
Эй, хороший способ иметь дело с. Однако как решить проблему, когда приходится разбивать большой текст на страницы и рисовать на холсте? Любое предложение приветствуется. - person Mark Delphi; 11.01.2021

Вам нужно разделить строку и нарисовать каждый фрагмент отдельно с увеличением y в зависимости от высоты шрифта.

Например:

var lines = text.split("\n"),
    x = 100, y = 100, fHeight = 16, // get x, y and proper font or line height here
    i = 0, line;

while(line = lines[i++]) {
    canvas.drawText(line, x, y, imgPaint);
    y += fHeight;
}
person Community    schedule 24.02.2015
comment
Я думаю, что OP больше заботится об определении разрывов строк, чем о многострочном аспекте. - person Mike M.; 24.02.2015

Что ж, уже довольно поздно добавлять еще один ответ, но если кто-то не хочет использовать StaticLayout, он может попробовать мою логику для многострочного текста.

Примечание. Этот код используется в методе onSizeChanged() View, а textArray — это переменная класса, в которой хранится каждая строка.

//This array will store all the words contained in input string
            val wordList = ArrayList<String>()

            //Temporary variable to store char or string
            var temp = ""

            it.trim().forEachIndexed { index, letter ->
                //Adding each letter to temp
                temp += letter

                //If letter is whiteSpace or last char then add it to wordList.
                //For example : Let input be "This is a Info text"
                //              since there is no whiteSpace after that last 't' then the last word
                //              will not be added to wordList there for checking for last letter is required
                //NOTE: the whiteSpace is also included in that word
                if (letter.isWhitespace() || index == it.length -1 ) {
                    wordList.add(temp)
                    //Resetting temp
                    temp = ""
                }
            }

            wordList.forEachIndexed { index, word ->
                //Measuring temp + word to check if their width in pixel is more than or equal to
                // the view's width + 60px(this is used so that word there is some space after each line. It can be changed)
                if (textPaint.measureText(temp + word) >= w - 60) {
                    textArray.add(temp)

                    //If adding last word to temp surpasses the required width then add the last word
                    // separately since the loop will be terminated after that
                    if (index == wordList.size - 1){
                        textArray.add(word)
                        return@forEachIndexed
                    }

                    //Resetting temp
                    temp = ""
                } else if (index == wordList.size - 1) {
                    //If adding last word to temp doesn't surpasses the required width the add that
                    // line to list
                    textArray.add(temp + word)
                    return@forEachIndexed
                }

                //Adding word to temp
                temp += word
            }

Затем в методе onDraw()

  textArray.forEachIndexed { index, singleLine ->
                    //x is set to 16f so that there is some space before first word
                    //y changes with each line i.e 1st line will be drawn at y = 60f, 2nd at 120f and so on
                    it.drawText(singleLine, 16f, (index + 1) * 60f, textPaint)
                }
person Manoj Chouhan    schedule 04.06.2020