如何在 Jetpack compose 中创建具有可跨越文本的 TextField

How to create TextField with spannable text in Jetpack compose

提问人:Slava 提问时间:11/9/2023 更新时间:11/9/2023 访问量:35

问:

如何使用可跨文本创建 TextField,其中每个单词都换行在单独的 spannable 中。
我需要使用 VisualTransformation 吗? 一定是这样的:

enter image description here

Transformation Spannable Jetpack

评论


答:

0赞 Dimitar 11/9/2023 #1

这应该可以做到:

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")
}

评论

0赞 Slava 11/9/2023
但是如果我想动态地做它,那么用户编写并创建可跨度后的空间?
0赞 Dimitar 11/9/2023
啊,好吧,那么我不确定你在写作时会如何实现它。您也许可以在可跨度的下方或上方进行输入,并在提交输入时,在最后一个空格后添加新的可跨度文本?
0赞 Slava 11/9/2023
然后用户在字段中写入,用户单击空格后,必须将单词 before 更改为可跨页文本。也许可以用 VisualTransformation 来完成吗?
0赞 Slava 11/9/2023
此外,您的示例将创建一个包含所有文本的 spannable