Android - Line height inconsistent on a TextView if using Bold or TypefaceSpan

441 Views Asked by At

I am building a reader app and have a custom class that expands a TextView with code to deal with pagination etc. The text is set from an Html format using

Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT, HtmlImageGetter(this, binding.textSurface, width), HtmlTagHandler(this))

It has a lot of functionalities for changing lineheights, font sizes, word spacing, etc on the fly. The layout is built with this code:

@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()
        }

One of the functionalities is also custom coloring of the text. So for example we could color the letter a/A in a different color. I am doing this with ForegroundColorSpan which works great. The problem I have is when I try to use a StyleSpan with a BOLD typeface on a letter.

This is a text without bolding. I am drawing the top, bottom, and baseline of every line to better show the effect: Correct line-height when no bolding span is present

And this is what I get when I try to bold the letter A: Wrong line-height on some lines

The TextView shrinks the line-height on the lines the bold letters are on, but ONLY on the lines where there is also a new line \n character present(the red dots on the image shows these).

I tested on the devices I have here and on android 7 it works correctly but the wrong line heights show on android 8.1 and android 11. Maybe they changed something on Android 8 but I can't figure out what...

Is there a way to force the use of the correct line-height on all lines consistently no matter what spans I use?

0

There are 0 best solutions below