Whenever I use the buildAnnotatedString I must write some sort of style using ParagraphStyle or SpanStlye. Sadly none of these 2 classes have modifiers to add some padding between every text (append)
This is what I'm getting right now. There should a small space between the background and the letters at the start and at the end of every text:

This is the code with the background:
val spanStyle = (
MaterialTheme.typography.body1.copy(
color = MaterialTheme.colors.onSurface,
fontWeight = FontWeight.W400,
fontSize = 17.sp,
letterSpacing = 0.25.sp,
background = MaterialTheme.colors.surface,
baselineShift = BaselineShift(0.2f),
)).toSpanStyle()
buildAnnotatedString {
withStyle(style = spanStyle) {
append("I write text here with background")
}
}
I've checked ParagraphStyle but the only thing related to vertical space is the lineHeight which obviously increase the height of every line but not the space between them.
Is there any way to add this little small space between every append() so background isn't coupled?
Edit:
This is what I have right now:

This is what I want to achieve, the horizontal padding at the start and end inside. TextIndent doesn't work because there's not a separation between the start background and start text.

I don't think it's possible with system methods, but you can draw background manually.
I'm adding only sample code here, fore more details of implementation see this answer.
@Composable
fun TestScreen(
) {
val baselineShiftMultiplier = 0.2f
val lineHeightMultiplier = 1.7f
val spanStyle = MaterialTheme.typography.body1.copy(
color = MaterialTheme.colors.onSurface,
fontWeight = FontWeight.W400,
fontSize = 17.sp,
letterSpacing = 0.25.sp,
baselineShift = BaselineShift(baselineShiftMultiplier),
)
var selectedPartPaths by remember { mutableStateOf(Path()) }
Text(
buildAnnotatedString {
withStyle(ParagraphStyle(lineHeight = spanStyle.fontSize * lineHeightMultiplier)) {
append("I write text here\n")
withStyle(style = spanStyle.toSpanStyle()) {
append("I write text here with background\n")
append("I write text here with background\n")
}
append("I write text here\n")
withStyle(style = spanStyle.toSpanStyle()) {
append("I write text here with background\n")
}
append("I write text here\n")
}
},
onTextLayout = { layoutResult ->
selectedPartPaths = Path().apply {
layoutResult.layoutInput.text.spanStyles.forEach { spanRange ->
val boundingBoxes = layoutResult
.getBoundingBoxesForRange(
start = spanRange.start,
end = spanRange.end
)
for (i in boundingBoxes.indices) {
val boundingBox = boundingBoxes[i]
addRect(
boundingBox.copy(
top = boundingBox.top + boundingBox.height * (1 - 1 / lineHeightMultiplier - baselineShiftMultiplier),
)
)
}
}
}
},
modifier = Modifier.drawBehind {
drawPath(selectedPartPaths, style = Fill, color = Color.LightGray)
}
)
}
fun TextLayoutResult.getBoundingBoxesForRange(start: Int, end: Int): List<Rect> {
var prevRect: Rect? = null
var firstLineCharRect: Rect? = null
val boundingBoxes = mutableListOf<Rect>()
for (i in start..end) {
val rect = getBoundingBox(i)
val isLastRect = i == end
// single char case
if (isLastRect && firstLineCharRect == null) {
firstLineCharRect = rect
prevRect = rect
}
// `rect.right` is zero for the last space in each line
// looks like an issue to me, reported: https://issuetracker.google.com/issues/197146630
if (!isLastRect && rect.right == 0f) continue
if (firstLineCharRect == null) {
firstLineCharRect = rect
} else if (prevRect != null) {
if (prevRect.bottom != rect.bottom || isLastRect) {
boundingBoxes.add(
firstLineCharRect.copy(right = prevRect.right)
)
firstLineCharRect = rect
}
}
prevRect = rect
}
return boundingBoxes
}
Result:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With