Как разместить текст в 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.
Представление частично решает проблему, т.е. реагирует на динамическое изменение размера. Что касается эллипсирования текста, вы можете добиться этого, настроив алгоритм, который я использовал для измерения высоты текста.