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
相关产品推荐
相关产品推荐

