Android Compose开发如何在软键盘上方显示粗体、斜体、下划线格式按钮
Jetpack Compose 软键盘上方富文本格式化按钮实现方案
完全可行,核心是通过WindowInsets监听软键盘状态,结合TextFieldValue的原生富文本能力实现,具体步骤如下:
前置配置
首先在Activity的onCreate方法中添加如下配置,确保Compose可以正确获取软键盘高度信息:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 关闭系统默认窗口适配,交给Compose处理Insets WindowCompat.setDecorFitsSystemWindows(window, false) setContent { // 你的Compose页面内容 } }
完整实现代码
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.FormatBold import androidx.compose.material.icons.filled.FormatItalic import androidx.compose.material.icons.filled.FormatUnderlined import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardOptions import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.ime import androidx.compose.foundation.text.KeyboardActions import androidx.compose.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalDensity @Composable fun RichTextInputPage() { val keyboardController = LocalSoftwareKeyboardController.current var textValue by remember { mutableStateOf(TextFieldValue("Write your text...")) } // 监听软键盘是否弹出 val isImeVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0 Column( modifier = Modifier .fillMaxSize() .systemBarsPadding() ) { TextField( value = textValue, modifier = Modifier .padding(16.dp) .fillMaxWidth() .weight(1f), placeholder = { Text(text = "John Doe") }, textStyle = TextStyle( color = Color.Gray, fontSize = 20.sp ), onValueChange = { textValue = it }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardActions = KeyboardActions( onDone = { keyboardController?.hide() // 自定义后续逻辑 } ) ) // 仅当软键盘弹出时显示格式化工具栏 if (isImeVisible) { Row( modifier = Modifier .fillMaxWidth() .background(MaterialTheme.colorScheme.surface) .imePadding() .padding(horizontal = 8.dp), horizontalArrangement = Arrangement.Start ) { // 加粗按钮 IconButton(onClick = { val selection = textValue.selection if (selection.start != selection.end) { val newText = buildAnnotatedString { append(textValue.annotatedString) addStyle( style = SpanStyle(fontWeight = FontWeight.Bold), start = selection.start, end = selection.end ) } textValue = textValue.copy(annotatedString = newText) } }) { Icon(Icons.Default.FormatBold, contentDescription = "加粗") } // 斜体按钮 IconButton(onClick = { val selection = textValue.selection if (selection.start != selection.end) { val newText = buildAnnotatedString { append(textValue.annotatedString) addStyle( style = SpanStyle(fontStyle = FontStyle.Italic), start = selection.start, end = selection.end ) } textValue = textValue.copy(annotatedString = newText) } }) { Icon(Icons.Default.FormatItalic, contentDescription = "斜体") } // 下划线按钮 IconButton(onClick = { val selection = textValue.selection if (selection.start != selection.end) { val newText = buildAnnotatedString { append(textValue.annotatedString) addStyle( style = SpanStyle(textDecoration = TextDecoration.Underline), start = selection.start, end = selection.end ) } textValue = textValue.copy(annotatedString = newText) } }) { Icon(Icons.Default.FormatUnderlined, contentDescription = "下划线") } } } } }
说明
- 以上代码基于Compose Material 3实现,如果你使用Material 2,替换对应的图标和主题色配置即可
- 样式修改逻辑默认是叠加样式,如果需要支持取消已添加的格式,可在点击按钮时先判断选中区间是否存在对应样式,存在则移除即可
- 富文本内容可根据需求转成HTML或Markdown格式持久化存储
内容的提问来源于stack exchange,提问作者justmee
相关产品推荐
相关产品推荐

