如何在Android中将文本与固定宽度和高度的StaticLayout相匹配

时间:2018-02-02 18:59:30

标签: android staticlayout

我正在尝试使用Canvas绘制文字,并且发现使用StaticLayout会自动处理换行符。我也想限制它的高度所以当文本太长时它会被椭圆化,但我文本容器的大小是动态的。我可以轻松地将宽度应用到StaticLayout,但无法找到一种做高度的方法。

我尝试使用TextUtils.ellipsize()但是有问题来获取行之间的间距。

2 个答案:

答案 0 :(得分:0)

您(和@ Cheok Yan Cheng)可能会尝试使用PagedTextView。该视图适用于Paginating text in Android

该视图部分解决了问题,即对动态尺寸更改做出了反应。对于文字省略,您可以通过自定义我用来测量高度文字的algorithm来实现。

答案 1 :(得分:0)

PerracoLabs的答案正确,但是,正如CheokYanCheng所说,最大行数的计算是不正确的(尽管即使在大多数情况下,它可能会产生正确的结果)。

不能为 StaticLayout 指定最大高度,除非通过指定最大行数间接地指定。无论如何,省略号与最大行数相关,因此,确定要返回解决方案的特定高度的最大行数是可行的。因此,我们如何确定合适的最大行数,以便可以按照PerracoLabs的说明来创建带有省略号的固定大小的StaticLayout ??

如果文本没有跨度影响文本的任何行高,则简单的计算就可以确定省略号前适合 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上发布了small project作为演示。

这是该应用程序的屏幕截图。

enter image description here