TextField
允许用户输入和修改文本。此页面描述了如何实现 TextField
、设置 TextField
输入样式以及配置其他 TextField
选项(例如键盘选项和视觉转换用户输入)。
选择 TextField
实现
有两种级别的 TextField
实现
TextField
是 Material Design 的实现。我们建议您选择此实现,因为它遵循 Material Design 指南BasicTextField
使用户能够通过硬件或软件键盘编辑文本,但没有提供提示或占位符等装饰。
@Composable fun SimpleFilledTextFieldSample() { var text by remember { mutableStateOf("Hello") } TextField( value = text, onValueChange = { text = it }, label = { Text("Label") } ) }
@Composable fun SimpleOutlinedTextFieldSample() { var text by remember { mutableStateOf("") } OutlinedTextField( value = text, onValueChange = { text = it }, label = { Text("Label") } ) }
设置 TextField
样式
TextField
和 BasicTextField
共享许多用于自定义它们的通用参数。 TextField
的完整列表可在 TextField
源代码 中找到。这是一个非详尽的列表,其中包含一些有用的参数
singleLine
maxLines
textStyle
@Composable fun StyledTextField() { var value by remember { mutableStateOf("Hello\nWorld\nInvisible") } TextField( value = value, onValueChange = { value = it }, label = { Text("Enter text") }, maxLines = 2, textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold), modifier = Modifier.padding(20.dp) ) }
当您的设计需要 Material TextField
或 OutlineTextField
时,我们建议使用 TextField
而不是 BasicTextField
。但是,在构建不需要 Material 规范中装饰的设计时,应使用 BasicTextField
。
使用 Brush API 设置输入样式
您可以使用 Brush API 在您的 TextField
中进行更高级的样式设置。以下部分描述了如何使用 Brush 为 TextField
输入添加彩色渐变。
有关使用 Brush API 设置文本样式的更多信息,请参阅 使用 Brush API 启用高级样式。
使用 TextStyle
实现彩色渐变
要在 TextField
中输入时实现彩色渐变,请将您选择的笔刷设置为 TextField
的 TextStyle
。在此示例中,我们使用带有 linearGradient
的内置笔刷来查看在文本输入 TextField
时出现的彩虹渐变效果。
var text by remember { mutableStateOf("") } val brush = remember { Brush.linearGradient( colors = rainbowColors ) } TextField( value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush) )
设置键盘选项
TextField
允许您设置键盘配置选项,例如键盘布局,或启用键盘支持的自动更正。如果软件键盘不符合此处提供的选项,则某些选项可能无法保证。以下是 支持的键盘选项 列表
capitalization
autoCorrect
keyboardType
imeAction
格式化输入
TextField
允许您在输入值上设置 VisualTransformation
,例如将字符替换为密码的 *
,或为信用卡号每 4 位插入连字符
@Composable fun PasswordTextField() { var password by rememberSaveable { mutableStateOf("") } TextField( value = password, onValueChange = { password = it }, label = { Text("Enter password") }, visualTransformation = PasswordVisualTransformation(), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) ) }
更多示例可在 VisualTransformationSamples
源代码 中找到。
清理输入
编辑文本时的一项常见任务是去除前导字符,或在每次更改时转换输入字符串。
作为模型,您应该假设键盘可能会在每次 onValueChange
中进行任意且大量的编辑。例如,如果用户使用自动更正、用表情符号替换单词或其他智能编辑功能,则可能会发生这种情况。为了正确处理这种情况,请在编写任何转换逻辑时假设传递给 onValueChange
的当前文本与将传递给 onValueChange
的先前或后续值无关。
要实现一个不允许前导零的文本字段,您可以通过在每次值更改时去除所有前导零来实现。
@Composable fun NoLeadingZeroes() { var input by rememberSaveable { mutableStateOf("") } TextField( value = input, onValueChange = { newText -> input = newText.trimStart { it == '0' } } ) }
要控制清理文本时的光标位置,请使用 TextFieldValue
的 TextField
重载作为状态的一部分。
状态最佳实践
以下是一系列定义和更新 TextField
状态的最佳实践,以防止应用程序中出现输入问题。
- 使用
MutableState
表示TextField
状态:避免使用像StateFlow
这样的反应式流来表示TextField
状态,因为这些结构可能会引入异步延迟。
class SignUpViewModel : ViewModel() { var username by mutableStateOf("") private set /* ... */ }
- 避免更新状态的延迟:当您调用
onValueChange
时,同步且立即更新您的TextField
// SignUpViewModel.kt class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() { var username by mutableStateOf("") private set fun updateUsername(input: String) { username = input } } // SignUpScreen.kt @Composable fun SignUpScreen(/*...*/) { OutlinedTextField( value = viewModel.username, onValueChange = { username -> viewModel.updateUsername(username) } /*...*/ ) }
- 在哪里定义状态:如果您的
TextField
状态需要在您输入时进行业务逻辑验证,则将状态提升到您的ViewModel
是正确的。如果不需要,您可以使用可组合项或状态持有者类作为真相来源。要了解有关在哪里提升状态的更多信息,请参阅 状态提升 文档。
为您推荐
- 注意:当 JavaScript 关闭时会显示链接文本
- 构建 Compose UI
- 状态和 Jetpack Compose
- 在 Compose 中保存 UI 状态