Android jetpack compose 中可组合的 TextField 的多样式文本编辑

Ami*_*mir 5 selectedtext textfield rich-text-editor textstyle android-jetpack-compose

我想更改TextFiled() 可组合项选定文本的文本样式( fontSize , color , fontWeight ,...) ,并使用 android jetpack compose中的按钮

(主要问题是,当我更改所选文本的文本样式时,TextField无法保存它,或者当我在 TextField 中添加/删除字母时,TextField会删除以前的文本样式。)

换句话说,当重组过程发生时,文本样式在 TextField() 中消失

在此输入图像描述

我的代码是:

@Composable
fun Show() {

    val inputText = remember{ mutableStateOf(TextFieldValue("This is a annotated text text"))}
    Column(
        modifier = Modifier.fillMaxSize().padding(5.dp) ,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        //=================== TextField
        CustomTextField(textInput = inputText)
        //==================== Button
        Button(onClick = {
            inputText.value = changeSegmentColor(inputText.value)

        }) {
            Text(text = "Change the text style of selected text")
        }
        //======================
    }
}

@Composable
fun CustomTextField (
    textInput:MutableState<TextFieldValue>
) {
    TextField(
        value = textInput.value , onValueChange = {
            textInput.value = it
        },
        modifier = Modifier.fillMaxWidth().heightIn(min = 200.dp) ,
    )
}
private fun changeSegmentColor(textFVal: TextFieldValue):TextFieldValue{
    val txtAnnotatedBuilder = AnnotatedString.Builder()
    val realStartIndex = textFVal.getTextBeforeSelection(textFVal.text.length).length
    val endIndex = realStartIndex + textFVal.getSelectedText().length
    txtAnnotatedBuilder.append(textFVal.annotatedString)
    val myStyle = SpanStyle(
        color = Color.Red ,
        fontSize = 16.sp ,
        background = Color.Green
    )
    txtAnnotatedBuilder.addStyle(myStyle ,realStartIndex ,endIndex)
    return textFVal.copy(annotatedString = txtAnnotatedBuilder.toAnnotatedString())
}
Run Code Online (Sandbox Code Playgroud)

Say*_*nna 0

@Composable
fun MultiStyleText(text: String, vararg styleRanges: StyleRange) {
    val annotatedString = buildAnnotatedString {
        var currentPosition = 0

        styleRanges.forEach { range ->
            val style = SpanStyle(
                color = range.textColor,
                fontSize = range.textSizeSp.sp,
                fontWeight = range.fontWeight
            )
            withStyle(style) {
                append(text.substring(currentPosition, range.endIndex))
            }
            currentPosition = range.endIndex
        }

        // Append the remaining text with the default style
        withStyle(SpanStyle()) {
            append(text.substring(currentPosition))
        }
    }

    Text(text = annotatedString)
}




data class StyleRange(
    val startIndex: Int,
    val endIndex: Int,
    val textColor: Color,
    val textSizeSp: Float,
    val fontWeight: FontWeight
)
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,定义一个接受 text 参数的MultiStyleText可组合项,以及可变数量的StyleRange类型的styleRanges。每个StyleRange指定要应用样式的文本范围的开始和结束索引,以及所需的文本颜色、文本大小和字体粗细。

在可组合项内,迭代 styleRanges并使用withStyle将相应的样式应用到指定的文本范围。使用追加函数在每个样式范围内追加文本的相关子字符串。最后,使用默认样式附加剩余文本。

要使用MultiStyleText可组合项,请提供所需的文本styleRanges

MultiStyleText(
    text = "This is a multi-style text example",
    StyleRange(0, 4, Color.Red, 18f, FontWeight.Bold),
    StyleRange(5, 7, Color.Blue, 14f, FontWeight.Normal),
    StyleRange(8, 13, Color.Green, 16f, FontWeight.Bold)
)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述