You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose文本样式实现求助:点击按钮后全文变粗

Jetpack Compose 实现选中文本加粗/斜体样式

你的代码核心问题是没有针对选中的文本区间精准应用样式,且prevPos固定为0,导致每次都给从开头到文本末尾的内容加粗,自然全部文本变粗。另外把样式处理放在onValueChange里逻辑也不对,应该在点击按钮时直接修改当前文本的样式。

以下是可正常工作的实现方案:

@Composable
fun StyledTextField() {
    // 跟踪是否开启粗体输入模式(光标未选中文本时,后续输入自动加粗)
    var isBoldMode by remember { mutableStateOf(false) }
    var textState by remember { mutableStateOf(TextFieldValue()) }

    Column(modifier = Modifier.padding(16.dp)) {
        Button(onClick = {
            isBoldMode = !isBoldMode
            val currentText = textState
            val selection = currentText.selection

            // 处理选中的文本区间
            if (selection.start != selection.end) {
                val start = selection.start
                val end = selection.end
                val newAnnotatedString = buildAnnotatedString {
                    // 保留原有文本的所有内容和样式
                    append(currentText.annotatedString)
                    // 检查当前区间是否已有粗体样式
                    val hasBold = currentText.annotatedString.getSpanStyles(start, end)
                        .any { it.style.fontWeight == FontWeight.Bold }

                    if (hasBold) {
                        // 移除粗体样式
                        removeStyle(SpanStyle(fontWeight = FontWeight.Bold), start, end)
                    } else {
                        // 添加粗体样式
                        addStyle(SpanStyle(fontWeight = FontWeight.Bold), start, end)
                    }
                }
                // 更新文本状态,保留原选中位置
                textState = currentText.copy(annotatedString = newAnnotatedString)
            }
        }) {
            Text(text = if (isBoldMode) "关闭粗体" else "开启粗体")
        }

        TextField(
            value = textState,
            onValueChange = { newText ->
                if (isBoldMode && newText.selection.start == newText.selection.end) {
                    // 粗体模式下无选中文本,新输入字符自动加粗
                    val cursorPos = newText.selection.start
                    val newAnnotatedString = buildAnnotatedString {
                        append(newText.text)
                        // 给刚输入的字符加粗(光标前的位置)
                        addStyle(SpanStyle(fontWeight = FontWeight.Bold), cursorPos - 1, cursorPos)
                    }
                    textState = newText.copy(annotatedString = newAnnotatedString)
                } else {
                    textState = newText
                }
            },
            textStyle = TextStyle(
                fontSize = 16.sp,
                lineHeight = 24.sp,
                color = Color.Black
            ),
            modifier = Modifier
                .clip(MaterialTheme.shapes.medium)
                .background(MaterialTheme.colors.surface)
        )
    }
}

关键逻辑说明

  • 选中文本样式切换:点击按钮时,先获取当前选中区间,检查该区间是否已有粗体样式,有则移除,无则添加,完全保留原有文本的其他样式。
  • 光标模式自动加粗:开启粗体模式后,若没有选中文本,新输入的字符会自动应用粗体样式。
  • 扩展斜体功能:只需复制按钮逻辑,将SpanStyle修改为fontStyle = FontStyle.Italic即可实现斜体切换。

内容的提问来源于stack exchange,提问作者AdnanKhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:42:42