我正在构建一个阅读器应用程序并有一个自定义类,该类使用代码扩展 TextView 以处理分页等。文本是使用 Html 格式设置的
Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT, HtmlImageGetter(this, binding.textSurface, width), HtmlTagHandler(this))
它有很多功能可以即时更改行高、字体大小、字间距等。布局是使用以下代码构建的:
@Suppress("DEPRECATION")
private fun from(layout: Layout) : Layout =
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
var tmpText = if(isUppercase) TextSegmentationNew.covertToUppercase(SpannedString(originalText)) else originalText
val formattedText = TextSegmentationNew.formatWithWordSpacing(tmpText, wordSpacing)
StaticLayout(
formattedText,
paint,
layout.width,
layout.alignment,
lineSpacingMultiplier,
lineSpacingExtra,
includeFontPadding)
} else {
var tmpText = if(isUppercase) TextSegmentationNew.covertToUppercase(SpannedString(originalText)) else originalText
val formattedText = TextSegmentationNew.formatWithWordSpacing(tmpText, wordSpacing)
StaticLayout.Builder
.obtain(formattedText, 0, formattedText.length, paint, layout.width)
.setAlignment(layout.alignment)
.setLineSpacing(lineSpacingExtra, lineSpacingMultiplier)
.setIncludePad(includeFontPadding)
.setUseLineSpacingFromFallbacks()
.setBreakStrategy(breakStrategy)
.setHyphenationFrequency(hyphenationFrequency)
.setJustificationMode()
.setMaxLines(maxLines)
.build()
}
其中一项功能也是自定义文本着色。例如,我们可以为字母 a/A 涂上不同的颜色。我正在使用 ForegroundColorSpan 执行此操作,效果很好。我遇到的问题是当我尝试在字母上使用带有 BOLD 字体的 StyleSpan 时。
这是一个没有加粗的文本。我正在绘制每条线的顶部、底部和基线以更好地显示效果: Correct line-height when no bolding span is present
这就是我尝试将字母 A 加粗时得到的结果: 某些行的行高错误
TextView 缩小了粗体字母所在行的行高,但仅在存在新行 \n 字符的行上(图像上的红点显示这些)。
我在我这里的设备和 android 7 上进行了测试,它工作正常,但在 android 8.1 和 android 11 上显示错误的行高。也许他们在 Android 8 上改变了一些东西,但我不知道是什么......
无论我使用什么跨度,有没有办法强制在所有行上始终使用正确的行高?