处理用户输入

TextField 可让用户输入和修改文本。本页介绍了 可以实现 TextField、设置 TextField 输入的样式,以及配置 其他 TextField 选项,例如键盘选项和视觉变化 用户输入。

选择“TextField”实现方式

TextField 实现分为两个级别:

  1. TextField 是 Material Design 实现。我们建议您选择 按照 Material Design 设计原则 指南: <ph type="x-smartling-placeholder">
      </ph>
    • 默认样式为填充
    • OutlinedTextField轮廓样式版本
  2. BasicTextField 可让用户通过硬件或软件编辑文本 键盘,但不提供提示或占位符等装饰。

@Composable
fun SimpleFilledTextFieldSample() {
    var text by remember { mutableStateOf("Hello") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

包含 Word 的可编辑文本字段

@Composable
fun SimpleOutlinedTextFieldSample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

可编辑的文字字段,带有紫色边框和标签。

样式 TextField

TextFieldBasicTextField 共用许多可对它们进行自定义的常用参数。完整的 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)
    )
}

多行 TextField,包括两个可编辑的行以及标签

如果您的设计要求TextField超过BasicTextField Material TextFieldOutlineTextField。但是,BasicTextField

使用 Brush API 设置输入样式

您可以使用 Brush APITextField 中进行更高级的样式设置。通过 以下部分介绍了如何使用 Brush 添加彩色渐变 转换为 TextField 输入。

如需详细了解如何使用 Brush API 设置文本样式,请参阅 使用 Brush API 启用高级样式设置

使用 TextStyle 实现彩色渐变

如需在 TextField 中输入内容时实现彩色渐变,请设置画笔 作为 TextFieldTextStyle。在本示例中,我们使用 使用 linearGradient 实现彩虹渐变效果 输入到TextField

var text by remember { mutableStateOf("") }
val brush = remember {
    Brush.linearGradient(
        colors = rainbowColors
    )
}
TextField(
    value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush)
)

使用 buildAnnotatedString 和 SpanStyle 以及 LinearGradient 仅自定义一段文本。
图 3.使用 buildAnnotatedStringSpanStyle 以及 linearGradient,仅自定义一段文本。

设置键盘选项

借助 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' }
        }
    )
}

如需在清理文本时控制光标位置,请使用 TextFieldTextFieldValue 重载作为状态的一部分。

有关状态的最佳实践

以下是定义和更新 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。如果没有,您可以使用可组合项或状态容器类作为 信息来源如需详细了解在哪里提升状态,请参阅 状态提升文档。