Как разместить текст в StaticLayout с фиксированной шириной и высотой в Android

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

Я пытался использовать TextUtils.ellipsize() но есть проблема, чтобы получить расстояние между строками.

0 ответов

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

Для StaticLayout нельзя указать максимальную высоту, кроме как косвенно путем указания максимального количества строк. Многоточие в любом случае привязано к максимальному количеству строк, поэтому определение максимального количества строк для определенной высоты, чтобы вернуться в решение, является правильным решением. Итак, как нам определить соответствующее максимальное количество строк, чтобы можно было создать StaticLayout фиксированного размера с многоточием, как объяснил PerracoLabs?

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

Следующая функция Kotlin определяет, сколько строк текста поместится в представление с фиксированной высотой и шириной. Предполагается, что каждая строка StaticLayout имеет заданную высоту (не влияющие на высоту промежутки). Верхняя строка имеет такую ​​же высоту, что и другие строки, но дополнена верхним отступом. К нижней строке добавлен нижний отступ.

       private fun getMaxLines(maxHeight: Int): Int {  
    // Build a dummy StaticLayout to get the internal measurements.  
    return makeStaticLayout("", width, 1).run {  
        val lineHeight = getLineBottom(0) - getLineTop(0) + topPadding - bottomPadding  
        (maxHeight - topPadding - bottomPadding) / lineHeight  
}  

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

Следующая функция Kotlin вычислит максимальное количество строк, проверив StaticLayout на наличие последней полной строки.

       private fun getMaxLinesByInspection(staticLayout: StaticLayout, maxHeight: Int): Int {
    var line = staticLayout.lineCount - 1
    while (line >= 0 && staticLayout.getLineBottom(line) >= maxHeight) {
        line--
    }
    return line + 1
}

Я разместил небольшой проект на GitHub в качестве демонстрации.

Вот скриншот приложения.

Вы (и @ Cheok Yan Cheng) можете попробовать использовать PagedTextView. Представление предназначено для разбивки текста на страницы в Android.

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

Другие вопросы по тегам