Cómo controlar las entradas del usuario

TextField permite que los usuarios ingresen y modifiquen texto. En esta página, se describe cómo puedes implementar TextField, diseñar la entrada de TextField y configurar otras opciones de TextField, como las opciones del teclado y la transformación visual la entrada del usuario.

Elige la implementación de TextField

Hay dos niveles de implementación de TextField:

  1. TextField es la implementación de Material Design. Te recomendamos que elijas de esta implementación, ya que sigue Material Design lineamientos:
    • El estilo predeterminado está relleno.
    • OutlinedTextField es la versión de estilo de contorno.
  2. BasicTextField permite a los usuarios editar texto mediante hardware o software teclado, pero no ofrece decoraciones, como pistas o marcadores de posición.

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

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

Un campo de texto editable que contiene la palabra

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

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

Campo de texto editable, con la etiqueta y un borde púrpura.

Estilo TextField

TextField y BasicTextField comparten muchos parámetros comunes de personalización. La lista completa de TextField está disponible en la fuente TextField correcto. Esta es una lista no exhaustiva de algunos de los parámetros útiles:

  • 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)
    )
}

Un TextField de varias líneas, con dos líneas editables más la etiqueta

Recomendamos usar TextField en lugar de BasicTextField cuando el diseño requiera una TextField o OutlineTextField de Material. Sin embargo, se debe usar BasicTextField cuando se crean diseños que no necesitan las decoraciones de la especificación de Material.

Entrada de estilo con la API de Brush

Puedes usar la API de Brush para obtener diseños más avanzados en tu TextField. El En la siguiente sección, se describe cómo usar un Brush para agregar un gradiente de color. a la entrada TextField.

Si quieres obtener más información sobre el uso de la API de Brush para aplicar estilo al texto, consulta Habilita el estilo avanzado con la API de Brush.

Cómo implementar gradientes de colores con TextStyle

Para implementar un gradiente de color mientras escribes en un elemento TextField, configura el pincel elegido como TextStyle para tu TextField. En este ejemplo, usamos un pincel integrado con un linearGradient para ver el efecto de gradiente del arcoíris como se escribe texto en TextField.

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

Se usa buildAnnotatedString y SpanStyle, junto con linearGradient, para personalizar solo un fragmento de texto.
Figura 3: Usa buildAnnotatedString y SpanStyle, junto con linearGradient, para personalizar solo un fragmento de texto.

Cómo configurar las opciones del teclado

TextField te permite establecer opciones de configuración del teclado, como el diseño, o bien habilitar la autocorrección si es compatible con el teclado. Es posible que algunas opciones no estén garantizadas si el teclado en pantalla no cumple con las opciones que se proporcionan aquí. Esta es la lista de los teclados compatibles :

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Entrada de formato

TextField te permite configurar un VisualTransformation para el valor de entrada, como reemplazar caracteres por * para contraseñas o insertar guiones cada 4 dígitos para un número de tarjeta de crédito:

@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)
    )
}

Un campo de entrada de texto con contraseña, con el texto enmascarado

Puedes encontrar más ejemplos en el código fuente de VisualTransformationSamples.

Entrada limpia

Una tarea común a la hora de editar texto es quitar caracteres iniciales o transformar la string de entrada cada vez que cambia.

Como modelo, debes suponer que el teclado puede realizar ediciones arbitrarias y grandes en cada instancia de onValueChange. Esto puede ocurrir, por ejemplo, si el usuario usa la autocorrección, reemplaza una palabra por un emoji o utiliza alguna otra función de edición inteligente. Para solucionar esto de forma correcta, escribe cualquier lógica de transformación suponiendo que el texto actual que se pasará a onValueChange no está relacionado con los valores anteriores o siguientes que se pasarán a onValueChange.

A fin de implementar un campo de texto que no permita ceros iniciales, puedes quitar todos los ceros iniciales en cada cambio de valor.

@Composable
fun NoLeadingZeroes() {
    var input by rememberSaveable { mutableStateOf("") }
    TextField(
        value = input,
        onValueChange = { newText ->
            input = newText.trimStart { it == '0' }
        }
    )
}

Para controlar la posición del cursor mientras limpias texto, usa la sobrecarga de TextFieldValue de TextField como parte del estado.

Prácticas recomendadas con el estado

A continuación, se incluye una serie de prácticas recomendadas para definir y actualizar TextField. para evitar problemas de entrada en tu app.

  • Usa MutableState para representar el estado TextField: Evitar. usando flujos reactivos como StateFlow para representar TextField, ya que estas estructuras pueden introducir retrasos asíncronos.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Evita demoras para actualizar el estado: Cuando llames a onValueChange, actualiza tu TextField de forma síncrona e inmediata:

// 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) }
        /*...*/
    )
}

  • Dónde definir el estado: Indica si el estado TextField requiere actividad. validaciones de lógica a medida que escribes, es correcto elevar el estado a tu ViewModel De lo contrario, puedes usar elementos componibles o una clase de contenedor de estado como la fuente de información. Para obtener más información sobre dónde elevar el estado, consulta la elevación de estado.