https://kotlinlang.org logo
Title
s

Stylianos Gakis

01/25/2023, 4:09 PM
When building an annotated string with
buildAnnotatedString
for a VisualTransformation for a TextField, I wanted some section of the text to be whatever the color already was, only with a lower alpha value. Best I found out how to do now was
// in composable context:
val mediumAlphaContentColor = LocalContentColor.current.copy(ContentAlpha.medium)
// Inside the visualTransformation not in a composable context
...
  buildAnnotatedString {
    append("")
    withStyle(SpanStyle(mediumAlphaContentColor))) {
      append("gray text")
    }
  }
}
But is there any API I can use to simply alter the alpha without changing the content color? Maybe in some span I am not gonna be using the LocalContentColor value and simply want to use whatever was there already. Maybe this isn’t possible though right?
j

james

01/25/2023, 11:08 PM
you should be able to do something like:
// let's just hardcode a text range here from 10-20
val textRange = TextRange(10, 20)
val originalSpanStyle = originalAnnotatedString
    .spanStyles
    .find { it.start == textRange.start && it.end == textRange.end }
    ?.item
val newSpanStyle = originalSpanStyle?.copy(brush = originalSpanStyle.brush, alpha = 0.5f)
// now apply newSpanStyle
if you wanted to update every SpanStyle in the whole string you could get a list of each of them including their ranges like this:
val newSpanStyles = originalAnnotatedString
    .spanStyles
    .map { originalSpanStyle ->
        originalSpanStyle.copy(
            item = originalSpanStyle.item.copy(brush = originalSpanStyle.item.brush, alpha = 0.5f)
        )
        
    }
then copy your original annotated string and apply each SpanStyle in
newSpanStyles
s

Stylianos Gakis

01/26/2023, 10:24 AM
I don’t know where in my range the text should be adjusted, since its position changed based on various variables, so adjusting a range isn’t quite something I can try. With the suggested solution, getting this new
newSpanStyles
, where would I plug that in? If I am inside my builder I don’t have access to my
originalAnnotatedString
yet, and if I am outside of it I’ve already finished building it, I can’t mutate it after the fact can I? Didn’t find a way to do this. And with all that said, when I am building my annotated string without providing any spanstyle in the first place, the
spanStyles
list seems to be empty. I seem to have to provide one myself in the first place, which brings me to the same issue of not know what the “default” color already was, which I don’t want to potentially override 🤔 So when no span styles are specified, after looking now for a bit, it seems like it may be all the way really deep in here, so if in my BasicTextField I do not specify a text color it simply defaults to
Color.Black
, but otherwise it fetches it from inside
textStyle
so I think I’d rather do smth like this:
val mediumContentAlpha = ContentAlpha.medium
val localContentColor = LocalContentColor.current
BasicTextField(
    textStyle = LocalTextStyle.current.copy(
        color = localContentColor,
    ),
    visualTransformation = visualTransformation@{ annotatedString: AnnotatedString ->
        val transformedString = buildAnnotatedString {
            if (...) { append(decimalSeparator) }
            append(" ")
            withStyle(SpanStyle(localContentColor.copy(mediumContentAlpha))) {
                append(component.currency)
            }
        }
        TransformedText(transformedString, ...)
    },
)
This way I am sure I keep the same color, but with a different alpha for that span only.