TextField es el componente de Jetpack Compose que permite a los usuarios ingresar y editar texto. El uso básico de TextField requiere de un estado para almacenar y actualizar el texto.
@Composable
fun BasicTextField() {
// Estado para almacenar el texto
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = { newText -> text = newText },
label = { Text("Ingresa tu nombre") }
)
}
Propiedades comunes de TextField
value y onValueChange
value: Representa el contenido actual del TextField.
onValueChange: Se ejecuta cada vez que cambia el texto, y recibe el nuevo valor.
label
La etiqueta es un texto que aparece dentro del campo, indicando al usuario qué debe ingresar.
TextField(
value = text,
onValueChange = { newText -> text = newText },
label = { Text("Nombre completo") }
)
placeholder
El placeholder es el texto que se muestra mientras el usuario no ha ingresado ningún valor.
TextField(
value = text,
onValueChange = { newText -> text = newText },
placeholder = { Text("Ejemplo: Juan Pérez") }
)
maxLines
Puedes controlar el número máximo de líneas que el usuario puede escribir en un TextField.
TextField(
value = text,
onValueChange = { newText -> text = newText },
label = { Text("Descripción") },
maxLines = 3 // Limitar a 3 líneas
)
singleLine
Si se desea que el TextField sea de una sola línea
Para crear un campo de contraseña, usa el modificador visualTransformation=PasswordVisualTransformation().
var password by remember { mutableStateOf("")}
TextField(
value = password,
onValueChange = { newPassword -> password = newPassword },
label = { Text("Contraseña") },
visualTransformation = PasswordVisualTransformation()
)
TextField con contraseña con opción mostrar/ocultar texto
Además, es posible configurar un icono al final del TextField que permita que se muestre/oculte la contraseña eque ha introducido el usuario
var passwordVisible by remember { mutableStateOf(false) }
var password by remember { mutableStateOf("")}
TextField(
value = password,
onValueChange = { newPassword -> password = newPassword },
label = { Text("Contraseña") },
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
// Permite agregar un ícono para alternar la visibilidad de la contraseña.
trailingIcon = {
val image = if (passwordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff
IconButton(onClick = { passwordVisible = !passwordVisible }) {
Icon(imageVector = image, contentDescription = null)
}
}
)
TextField numérico
Es posible hacer que un TextField solo acepte números establenciendo un teclado numérico y haciendo que la lambda onValueChange impida que cambie el estado cuando el nuevo texto no es un número
@Composable
fun NumericTextField() {
var number by remember { mutableStateOf(1) }
TextField(
value = number.toString(),
// Modificamos el teclado del usuario de forma que solo haya números
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
// La lambda se encarga de evitar que meta letras en el campo
onValueChange = { newText ->
number = if (newText.isBlank()) 0 else newText.toIntOrNull() ?: number
})
}
TextField multilínea y ajuste de tamaño
Para permitir un campo multilínea que ajuste su tamaño según el contenido, puedes usar BasicTextField o ajustar TextField con maxLines y modifier.
TextField(
value = text,
onValueChange = { newText -> text = newText },
label = { Text("Comentario") },
modifier = Modifier
.fillMaxWidth()
.heightIn(min = 56.dp, max = 200.dp),
maxLines = 5 // Limitar a 5 líneas
)
TextField avanzado: BasicTextField
BasicTextField es una versión más personalizable de TextField, en la que puedes definir completamente el diseño, aunque requiere más control manual. Aquí tienes un ejemplo:
@Composable
fun CustomBasicTextField() {
var text by remember { mutableStateOf("Escribe aquí") }
BasicTextField(
value = text,
onValueChange = { newText -> text = newText },
decorationBox = { innerTextField ->
Row(
Modifier
.background(Color.LightGray)
.padding(16.dp)
.fillMaxWidth()
) {
innerTextField() // Aquí va el contenido editable
}
}
)
}