如何在 Android 中以固定宽度和高度将文本放入 StaticLayout?
How to fit text into StaticLayout with fixed width and height in Android?
我正在尝试使用 Canvas
绘制文本,发现使用 StaticLayout
会自动处理换行符。我还想限制它的高度,以便当文本太长时它会被椭圆化,但文本容器的大小是动态的。我可以轻松地将宽度应用于 StaticLayout
,但无法找到一种方法来实现高度。
我尝试使用 TextUtils.ellipsize()
,但在获取行间距时遇到问题。
你(和@Cheok Yan Cheng) might try to make use of PagedTextView. The view is intended for .
视图部分解决了问题,即对动态大小变化做出反应。至于文本省略,您可以通过自定义 algorithm 我用来测量文本高度的方法来实现。
PerracoLabs 有正确的答案,但是,正如 CheokYanCheng 所说,最大行数的计算是错误的(尽管它可能会在很多情况下产生正确的结果)。
不能为 StaticLayout 指定最大高度,除非间接指定最大行数。无论如何,省略号与最大行数有关,因此确定特定高度的最大行数以返回解决方案是可行的方法。那么,我们如何确定适当的最大行数,以便可以像 PerracoLabs 解释的那样创建带省略号的 fixed-size StaticLayout。?
如果文本没有影响任何文本行高度的跨度,那么一个简单的计算就可以确定将适合省略号之前的 StaticLayout 的最大行数.
以下 Kotlin 函数将确定多少行文本将适合具有固定高度和宽度的视图。假设 StaticLayout 的每一行都有一个设置的高度(没有 height-effecting 跨度)。顶行与其他行具有相同的高度,但它被顶部填充增加了。底线添加了底部填充。
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 上发布了一个 small project 作为演示。
这是应用程序的屏幕截图。
我正在尝试使用 Canvas
绘制文本,发现使用 StaticLayout
会自动处理换行符。我还想限制它的高度,以便当文本太长时它会被椭圆化,但文本容器的大小是动态的。我可以轻松地将宽度应用于 StaticLayout
,但无法找到一种方法来实现高度。
我尝试使用 TextUtils.ellipsize()
,但在获取行间距时遇到问题。
你(和@Cheok Yan Cheng) might try to make use of PagedTextView. The view is intended for
视图部分解决了问题,即对动态大小变化做出反应。至于文本省略,您可以通过自定义 algorithm 我用来测量文本高度的方法来实现。
PerracoLabs 有正确的答案,但是,正如 CheokYanCheng 所说,最大行数的计算是错误的(尽管它可能会在很多情况下产生正确的结果)。
不能为 StaticLayout 指定最大高度,除非间接指定最大行数。无论如何,省略号与最大行数有关,因此确定特定高度的最大行数以返回解决方案是可行的方法。那么,我们如何确定适当的最大行数,以便可以像 PerracoLabs 解释的那样创建带省略号的 fixed-size StaticLayout。?
如果文本没有影响任何文本行高度的跨度,那么一个简单的计算就可以确定将适合省略号之前的 StaticLayout 的最大行数.
以下 Kotlin 函数将确定多少行文本将适合具有固定高度和宽度的视图。假设 StaticLayout 的每一行都有一个设置的高度(没有 height-effecting 跨度)。顶行与其他行具有相同的高度,但它被顶部填充增加了。底线添加了底部填充。
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 上发布了一个 small project 作为演示。
这是应用程序的屏幕截图。