如何使Paint.breakText尊重自动换行?

时间:2019-07-09 03:48:23

标签: android textview word-wrap android-paint

我想计算一些文本需要多少行才能适合固定宽度的TextView。我为此使用了Paint.breakText

int maxWidth = WIDTH_IN_PIXELS;
int index = 0;
int linecnt = 0;
while (true) {
    float[] measuredWidth = new float[1];
    int advances = labelView.getPaint().breakText(text, index, text.length(), true,  maxWidth, measuredWidth);
    linecnt += 1;
    index += advances;
    if(index>=desc.length()) break;           
}

但是,计算出的linecnt总是比实际需要的少一。经过进一步研究,我发现该API会在单词中的任意点中断文本,但是当TextView布局文本时,它永远不会中断一个单词:

// textBreak:
Hello Wo
rld
// Real layout:
Hello
World

如何使breakText尊重自动换行?还是有其他方法可以做到这一点?

p.s。我知道我总是可以在循环内移回单词的开头,但这看起来很笨拙,并不适用于每种语言。我确信Android有一些优雅的方法可以做到这一点,但是我不知道要使用的API /标记。

p.p.s有时TextView使用破折号(-)在行中打断一个长字,其规则尚不清楚。

1 个答案:

答案 0 :(得分:0)

这感觉有点棘手,并且不会在中间用破折号自动断字,但是我的想法是我有一串断字字符,只是向后迭代,直到遇到断字为止。如果单词太长且没有破字符,只需在行尾中断即可。

var wordCharsToFit = labelView.getPaint().breakText(text, index, text.length(), true,  maxWidth, measuredWidth);
while (wordCharsToFit > 0 && (
            lyrics.length > wordCharsToFit && !"‐–〜゠= \t\r\n".contains(lyrics[wordCharsToFit]) ||
            chords.length > wordCharsToFit && !"‐–〜゠= \t\r\n".contains(chords[wordCharsToFit])
)) {
    wordCharsToFit -= 1

    if (wordCharsToFit == 0) {
        wordCharsToFit = totalCharsToFit
        break
    }
}