文本输入
2026/1/31大约 4 分钟
文本输入
本文档覆盖 Jetpack Compose 中常用的文本输入控件与相关 API:TextField、OutlinedTextField、BasicTextField,以及键盘配置、视觉变换、状态管理、焦点与无障碍等常见用法与示例。
概览
TextField:带背景的 Material 文本输入,常用于表单中的主输入项。OutlinedTextField:带边框的输入框,外观为轮廓样式。BasicTextField:基础输入控件,无样式,适合自定义输入表现(需要自己绘制装饰)。
常用参数(大多数输入控件共有)
value: String/value: TextFieldValue:输入内容。TextFieldValue包含选择与光标信息,通常在需要文本选择或光标控制时使用。onValueChange: (String) -> Unit:文本改变回调。modifier: Modifier:布局/尺寸/交互样式。label: @Composable?:浮动标签(通常在TextField中使用)。placeholder: @Composable?:占位文本。leadingIcon/trailingIcon:前置/后置图标区域。singleLine: Boolean:是否单行输入。maxLines: Int:最大行数。isError: Boolean:错误状态(会影响颜色与语义)。enabled: Boolean:是否可编辑。readOnly: Boolean:只读但可选中文本。visualTransformation: VisualTransformation:文本视觉变换(如密码隐藏、格式化)。keyboardOptions: KeyboardOptions:键盘类型、动作、自动大写等配置(keyboardType、imeAction、capitalization、autoCorrect)。keyboardActions: KeyboardActions:响应 IME 操作(onDone、onNext、onSearch等)。interactionSource: MutableInteractionSource:监听交互状态(按下、悬停、聚焦)。
颜色与样式
- 使用
TextFieldDefaults.textFieldColors()或TextFieldDefaults.outlinedTextFieldColors()定制文本、容器、占位、光标、错误颜色等。 TextFieldDefaults还提供minHeight、contentPadding等常量用于保持样式一致。
状态与保存
- 推荐用
var text by rememberSaveable { mutableStateOf("") }保存简单字符串状态,跨配置更改(旋转)也能恢复。 - 需要完整光标/选择信息时使用
TextFieldValue:var state by remember { mutableStateOf(TextFieldValue()) }。
焦点与键盘控制
LocalFocusManager.current用于隐藏键盘或移动焦点:focusManager.clearFocus()。FocusRequester可用于请求聚焦:val requester = remember { FocusRequester() },Modifier.focusRequester(requester)。keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })常用于表单提交后关闭键盘。
视觉变换与掩码
PasswordVisualTransformation():默认的密码遮挡(*号或圆点)。- 自定义
VisualTransformation可实现格式化(如信用卡分组、分隔符)或掩码。
示例:密码输入带可见性切换
@Composable
fun PasswordFieldExample() {
var password by rememberSaveable { mutableStateOf("") }
var visible by rememberSaveable { mutableStateOf(false) }
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = { Text("密码") },
visualTransformation = if (visible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
val image = if (visible) Icons.Default.Visibility else Icons.Default.VisibilityOff
IconButton(onClick = { visible = !visible }) {
Icon(imageVector = image, contentDescription = if (visible) "隐藏密码" else "显示密码")
}
},
singleLine = true,
modifier = Modifier.fillMaxWidth()
)
}示例:文本字段与 IME 操作
@Composable
fun ImeActionExample() {
var text by rememberSaveable { mutableStateOf("") }
val focusManager = LocalFocusManager.current
TextField(
value = text,
onValueChange = { text = it },
label = { Text("搜索") },
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Search,
keyboardType = KeyboardType.Text
),
keyboardActions = KeyboardActions(
onSearch = {
// 处理搜索
focusManager.clearFocus()
}
),
modifier = Modifier.fillMaxWidth()
)
}示例:带计数器与错误提示
@Composable
fun CounterAndErrorExample() {
var text by rememberSaveable { mutableStateOf("") }
val max = 20
val isError = text.length > max
Column(modifier = Modifier.fillMaxWidth()) {
OutlinedTextField(
value = text,
onValueChange = { if (it.length <= max) text = it },
label = { Text("备注") },
isError = isError,
modifier = Modifier.fillMaxWidth()
)
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
Text(text = "${text.length}/$max", color = if (isError) Color.Red else Color.Gray)
}
}
}示例:自定义 BasicTextField 的装饰(decorationBox)
@Composable
fun CustomBasicTextField() {
var text by rememberSaveable { mutableStateOf("") }
BasicTextField(
value = text,
onValueChange = { text = it },
modifier = Modifier
.border(1.dp, Color.Gray, RoundedCornerShape(8.dp))
.padding(8.dp),
singleLine = true,
decorationBox = { innerTextField ->
if (text.isEmpty()) {
Text("请输入内容", color = Color.Gray)
}
innerTextField()
}
)
}文本格式与过滤
- Compose 本身没有直接的输入掩码 API,但可以在
onValueChange中过滤或格式化输入(例如限制字符、自动插入分隔符)。 - 对复杂场景推荐结合
visualTransformation(展示)和onValueChange(数据)实现。
可访问性与语义
- 使用
semantics或contentDescription补充控件语义,例如错误提示、必填说明等:Modifier.semantics { contentDescription = "用户名输入" } isError会影响语义,辅助工具可根据其状态提示用户。
性能与最佳实践
- 尽量把状态提升(state hoisting),使父组件控制输入状态,便于测试与重用。
- 使用
rememberSaveable保存用户输入以便在配置变更时恢复。 - 避免在
onValueChange中做重型计算;如需验证或网络请求,使用 debounce 或在提交时处理。
速查(常用 API)
TextField/OutlinedTextField/BasicTextFieldvalue/onValueChange/TextFieldValuevisualTransformation/PasswordVisualTransformation()keyboardOptions(KeyboardType, ImeAction, Capitalization)keyboardActions(onDone, onNext, onSearch, onGo)isError/placeholder/label/leadingIcon/trailingIconTextFieldDefaults.textFieldColors()/outlinedTextFieldColors()FocusRequester/LocalFocusManager
如果你希望我把这些示例拆成可直接复制到 Android Studio 的 @Preview 屏幕文件或添加更复杂的输入掩码示例,我可以继续生成并验证。
测试代码:
@Composable
fun TextComponents() {
// 这个 remember 相当于是一个观察者,当输入框的值改变时,myTextValue.value 会改变
// 无需重新渲染 TextField,提高性能。
val myTextValue = remember {
mutableStateOf("")
}
// todo: 这个 by 的用法 相当于 myTextValue.value
var myTextValue2 by remember {
mutableStateOf("")
}
Column {
TextField(
value = myTextValue.value,
placeholder = { Text(text = "请输入") },
onValueChange = {
myTextValue.value = it
myTextValue2 = it
})
Text("输入的内容是:")
Text(text = myTextValue.value)
Spacer(modifier = Modifier.height(20.dp))
Text(text = "2输入的内容是:")
Text(text = myTextValue2)
}
}