How to create TextField with spannable text in Jetpack compose

623 Views Asked by At

How to create TextField with spannable text where every word is wrapped in separate spannable.
Do I need to use VisualTransformation? Must be something like that:

enter image description here

1

There are 1 best solutions below

4
On

This should do it:

import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.rememberMaterial3Colors
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp

@Composable
fun SpannableTextField(text: String) {
    val spannableText = createSpannableText(text)
    
    Surface(
        modifier = Modifier.padding(16.dp),
        color = MaterialTheme.colorScheme.background
    ) {
        BasicTextField(
            value = TextFieldValue(text = spannableText),
            textStyle = MaterialTheme.typography.body1.copy(fontSize = 16.sp),
            onValueChange = {},
            singleLine = true
        )
    }
}

@Composable
private fun createSpannableText(text: String): AnnotatedString {
    val words = text.split(" ")

    return AnnotatedString.Builder().apply {
        words.forEachIndexed { index, word ->
            val start = length
            val end = start + word.length

            addStyle(
                style = SpanStyle(
                    color = getRandomColor(),
                    fontSize = 16.sp
                ),
                start = start,
                end = end
            )

            append(word)

            if (index < words.size - 1) append(" ")
        }
    }.toAnnotatedString()
}

private fun getColor(): Color {
    // You can create logic for generating random color here.
    return Color.Red
}

@Preview
@Composable
fun SpannableTextFieldPreview() {
    SpannableTextField(text = "transformation spannable jetpack")
}