TextField
permite a los usuarios ingresar y modificar texto. Existen dos tipos de
campos de texto que puedes usar: campos de texto basados en el estado y
campos de texto basados en valores. Selecciona el tipo para el que deseas mostrar contenido:
Te recomendamos que uses campos de texto basados en el estado, ya que proporcionan un enfoque más completo y confiable para administrar el estado de un TextField
. En la siguiente tabla, se describen las diferencias entre estos tipos de campos de texto y se incluyen las ventajas clave que ofrecen los campos de texto basados en el estado:
Función |
Campos de texto basados en valores |
Campos de texto basados en el estado |
Beneficios basados en el estado |
---|---|---|---|
Administración de estado |
Actualiza el estado del campo de texto con la devolución de llamada |
Usa explícitamente un objeto |
|
Transformación visual |
Usa |
Usa |
|
Límites de líneas |
Acepta |
Usa |
|
Campo de texto seguro |
N/A |
|
|
En esta página, se describe cómo
puedes implementar TextField
, aplicar diseño a la entrada de TextField
y configurar
otras opciones de TextField
, como las opciones del teclado y la transformación visual
de la entrada del usuario.
Elige la implementación de TextField
Existen dos niveles de implementación de TextField
:
TextField
es la implementación de Material Design. Te recomendamos que elijas esta implementación, ya que sigue los lineamientos de Material Design:- El estilo predeterminado está relleno.
OutlinedTextField
es la versión de diseño con contorno.
BasicTextField
permite a los usuarios editar texto con el teclado en pantalla o físico, pero no proporciona decoraciones como sugerencias o marcadores de posición.
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
OutlinedTextField( state = rememberTextFieldState(), label = { Text("Label") } )
Estilo TextField
TextField
y BasicTextField
comparten muchos parámetros comunes de personalización.
La lista completa para TextField
está disponible en el código fuente de TextField
. Esta es una lista no exhaustiva de algunos de los parámetros útiles:
textStyle
lineLimits
TextField( state = rememberTextFieldState("Hello\nWorld\nInvisible"), lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2), placeholder = { Text("") }, textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold), label = { Text("Enter text") }, modifier = Modifier.padding(20.dp) )
Recomendamos usar TextField
en lugar de BasicTextField
cuando el diseño llame a un TextField
o OutlinedTextField
de Material. Sin embargo, BasicTextField
debe usarse cuando se crean diseños que no necesitan las decoraciones de la especificación de Material.
Configura los límites de línea
Los elementos componibles de TextField
admiten el desplazamiento a lo largo de un solo eje. El comportamiento de desplazamiento se determina mediante el parámetro lineLimits
. Los TextField
configurados para una sola línea se desplazan horizontalmente, mientras que los TextField
de varias líneas se desplazan verticalmente.
Usa TextFieldLineLimits
para elegir la configuración de línea adecuada para tu TextField
:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine )
La configuración de SingleLine
tiene las siguientes características:
- El texto nunca se une y no permite líneas nuevas.
TextField
siempre tiene una altura fija.- Si el texto se desborda, se desplaza horizontalmente.
TextField( state = rememberTextFieldState("Hello\nWorld\nHello\nWorld"), lineLimits = TextFieldLineLimits.MultiLine(1, 4) )
La configuración de MultiLine
tiene las siguientes características:
- Acepta dos parámetros:
minHeightInLines
ymaxHeightInLines
. - El campo de texto tiene al menos
minHeightInLines
de altura. - Si el texto se desborda, se ajustará.
- Si el texto requiere más líneas, el campo crece hasta que mide
maxHeightInLines
de altura y se desplaza verticalmente.
Aplica estilo a la entrada con la API de Brush
Puedes usar la API de Brush para aplicar estilos más avanzados en tu TextField
.
En la siguiente sección, se describe cómo puedes usar un pincel para agregar un gradiente coloreado a la entrada de TextField
.
Para obtener más información sobre el uso de la API de Brush para aplicar diseño al texto, consulta Habilita el diseño avanzado con la API de Brush.
Implementa gradientes de colores con TextStyle
Para implementar un gradiente de color mientras escribes dentro de un TextField
, configura el pincel que elijas como un TextStyle
para tu TextField
. En este ejemplo, usamos un pincel integrado con un linearGradient
para ver el efecto de gradiente de arco iris a medida que se escribe el texto en TextField
.
val brush = remember { Brush.linearGradient( colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta) ) } TextField( state = rememberTextFieldState(), textStyle = TextStyle(brush = brush) )

TextField
.Administra el estado del campo de texto
TextField
usa una clase de contenedor de estado dedicada llamada TextFieldState
para su contenido y selección actual. TextFieldState
está diseñado para elevarse
dondequiera que se adapte a tu arquitectura. TextFieldState
proporciona 2 propiedades principales:
initialText
: Es el contenido deTextField
.initialSelection
: Indica dónde se encuentra el cursor o la selección en un momento determinado.
Lo que diferencia a TextFieldState
de otros enfoques, como la devolución de llamada onValueChange
, es que TextFieldState
encapsula por completo todo el flujo de entrada. Esto incluye usar las estructuras de datos de respaldo correctas, intercalar
filtros y formateadores, y también sincronizar todos los cambios que provienen de diferentes
fuentes.
Puedes usar TextFieldState()
para elevar el estado en TextField
. Para ello, te recomendamos que uses la función rememberTextFieldState()
.
rememberTextFieldState()
crea la instancia de TextFieldState
en tu elemento componible, garantiza que se recuerde el objeto de estado y proporciona la funcionalidad de guardar y restablecer integrada:
val usernameState = rememberTextFieldState() TextField( state = usernameState, lineLimits = TextFieldLineLimits.SingleLine, placeholder = { Text("Enter Username") } )
rememberTextFieldState
puede tener un parámetro en blanco o un valor inicial que se pasa para representar el valor del texto en la inicialización. Si se pasa un valor diferente en una recomposición posterior, no se actualiza el valor del estado. Para actualizar el estado después de que se inicialice, llama a los métodos de edición en TextFieldState
.
TextField( state = rememberTextFieldState(initialText = "Username"), lineLimits = TextFieldLineLimits.SingleLine, )

TextField
con "Nombre de usuario" como texto inicial.Modifica el texto con TextFieldBuffer
Un TextFieldBuffer
funciona como un contenedor de texto editable, similar en función a un StringBuilder
. Contiene el contenido de texto y la información sobre la selección actual.
A menudo, se encuentra TextFieldBuffer
como un alcance del receptor en funciones como TextFieldState.edit
, InputTransformation.transformInput
o OutputTransformation.transformOutput
. En estas funciones, puedes leer o
actualizar el TextFieldBuffer
según sea necesario. Luego, estos cambios se confirman en TextFieldState
o se pasan a la canalización de renderización en el caso de OutputTransformation
.
Puedes usar funciones de edición estándar, como append
, insert
, replace
o delete
, para modificar el contenido del búfer. Para cambiar el estado de selección, configura directamente su variable selection: TextRange
o usa funciones de utilidad, como placeCursorAtEnd
o selectAll
. La selección en sí se representa con un TextRange
, en el que el índice de inicio es inclusivo y el índice de finalización es exclusivo.
Un TextRange
con valores de inicio y finalización idénticos, como (3, 3)
, indica una posición del cursor sin caracteres seleccionados actualmente.
val phoneNumberState = rememberTextFieldState() LaunchedEffect(phoneNumberState) { phoneNumberState.edit { // TextFieldBuffer scope append("123456789") } } TextField( state = phoneNumberState, inputTransformation = InputTransformation { // TextFieldBuffer scope if (asCharSequence().isDigitsOnly()) { revertAllChanges() } }, outputTransformation = OutputTransformation { if (length > 0) insert(0, "(") if (length > 4) insert(4, ")") if (length > 8) insert(8, "-") } )
Editar texto en TextFieldState
Existen varios métodos que te permiten editar el estado directamente a través de tu variable de estado:
edit
: Te permite editar el contenido del estado y te brinda funcionesTextFieldBuffer
para que puedas usar métodos comoinsert
,replace
,append
y mucho más.val usernameState = rememberTextFieldState("I love Android") // textFieldState.text : I love Android // textFieldState.selection: TextRange(14, 14) usernameState.edit { insert(14, "!") } // textFieldState.text : I love Android! // textFieldState.selection: TextRange(15, 15) usernameState.edit { replace(7, 14, "Compose") } // textFieldState.text : I love Compose! // textFieldState.selection: TextRange(15, 15) usernameState.edit { append("!!!") } // textFieldState.text : I love Compose!!!! // textFieldState.selection: TextRange(18, 18) usernameState.edit { selectAll() } // textFieldState.text : I love Compose!!!! // textFieldState.selection: TextRange(0, 18)
setTextAndPlaceCursorAtEnd
: Borra el texto actual, lo reemplaza por el texto determinado y establece el cursor al final.usernameState.setTextAndPlaceCursorAtEnd("I really love Android") // textFieldState.text : I really love Android // textFieldState.selection : TextRange(21, 21)
clearText
: Borra todo el texto.usernameState.clearText() // textFieldState.text : // textFieldState.selection : TextRange(0, 0)
Para ver otras funciones de TextFieldState
, consulta la referencia de TextFieldState
.
Cómo modificar la entrada del usuario
En las siguientes secciones, se describe cómo modificar la entrada del usuario.
La transformación de entrada te permite filtrar la entrada TextField
mientras el usuario escribe, mientras que la transformación de salida formatea la entrada del usuario antes de que se muestre en pantalla.
Filtra la entrada del usuario con transformaciones de entrada
Una transformación de entrada te permite filtrar la entrada del usuario. Por ejemplo, si tu TextField
recibe un número de teléfono estadounidense, solo debes aceptar 10 dígitos. Los resultados de InputTransformation
se guardan en TextFieldState
.
Existen filtros integrados para casos de uso comunes de InputTransformation
. Para limitar la longitud, llama a InputTransformation.maxLength()
:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine, inputTransformation = InputTransformation.maxLength(10) )
Transformaciones de entrada personalizadas
InputTransformation
es una interfaz de una sola función. Cuando implementes tu InputTransformation
personalizado, deberás anular TextFieldBuffer.transformInput
:
class CustomInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { } }
Para un número de teléfono, agrega una transformación de entrada personalizada que solo permita que se escriban dígitos en TextField
:
class DigitOnlyInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { if (!TextUtils.isDigitsOnly(asCharSequence())) { revertAllChanges() } } }
Encadena transformaciones de entrada
Para agregar varios filtros a tu entrada de texto, encadena InputTransformation
con la función de extensión then
. Los filtros se ejecutan de forma secuencial. Como
recomendación, aplica primero los filtros más selectivos para evitar
transformaciones innecesarias en los datos que, en última instancia, se filtrarían.
TextField( state = rememberTextFieldState(), inputTransformation = InputTransformation.maxLength(6) .then(CustomInputTransformation()), )
Después de agregar transformaciones de entrada, la entrada TextField
acepta 10 dígitos como máximo.
Dale formato a la entrada antes de que se muestre
Los OutputTransformation
te permiten dar formato a la entrada del usuario antes de que se renderice en la pantalla. A diferencia de InputTransformation
, el formato que se realiza a través de OutputTransformation
no se guarda en TextFieldState
. En función del ejemplo de número de teléfono anterior, debes agregar paréntesis y guiones en los lugares adecuados:

Esta es la forma actualizada de controlar los VisualTransformation
en los TextField
basados en valores, con la diferencia clave de que no tienes que calcular sus asignaciones de offset.
OutputTransformation
es una interfaz de método abstracto único. Para implementar un OutputTransformation
personalizado, debes anular el método transformOutput
:
class CustomOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { } }
Para dar formato a un número de teléfono, agrega un paréntesis de apertura en el índice 0, un paréntesis de cierre en el índice 4 y un guion en el índice 8 a tu OutputTransformation
:
class PhoneNumberOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { if (length > 0) insert(0, "(") if (length > 4) insert(4, ")") if (length > 8) insert(8, "-") } }
Luego, agrega tu OutputTransformation
a TextField
:
TextField( state = rememberTextFieldState(), outputTransformation = PhoneNumberOutputTransformation() )
Cómo funcionan las transformaciones en conjunto
En el siguiente diagrama, se muestra el flujo de entrada de texto a la transformación y, luego, a la salida:

- La entrada se recibe de la fuente de entrada.
- La entrada se filtra a través de un
InputTransformation
, que se guarda en TextFieldState. - La entrada se pasa a través de un
OutputTransformation
para aplicarle formato. - La entrada se presenta en
TextField
.
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 las opciones de teclado compatibles:
capitalization
autoCorrect
keyboardType
imeAction
La clase KeyboardOptions
ahora incluye un nuevo parámetro booleano, showKeyboardOnFocus
, que se usa específicamente para los componentes TextField
integrados en TextFieldState
. Esta opción rige el comportamiento del teclado en software cuando TextField
adquiere el enfoque a través de medios distintos de la interacción directa del usuario (por ejemplo, de forma programática).
Cuando KeyboardOptions.showKeyboardOnFocus
se establece como verdadero, el teclado en software no aparece automáticamente si TextField
obtiene el enfoque de forma indirecta. En esos casos, el usuario debe presionar de forma explícita el TextField
para revelar el teclado.
Define la lógica de interacción del teclado
El botón de acción del teclado en software de Android permite respuestas interactivas dentro de tu aplicación. Para obtener más información sobre cómo configurar el botón de acción, consulta la sección Cómo configurar las opciones del teclado.

Para definir lo que ocurre cuando un usuario presiona este botón de acción, usa el parámetro onKeyboardAction
. Este parámetro acepta una interfaz funcional opcional llamada KeyboardActionHandler
. La interfaz KeyboardActionHandler
contiene un solo método, onKeyboardAction(performDefaultAction: () -> Unit)
.
Si proporcionas una implementación para este método onKeyboardAction
, puedes introducir una lógica personalizada que se ejecute cuando un usuario presione el botón de acción del teclado.
Varios tipos de acciones de teclado estándar incluyen comportamientos predeterminados integrados.
Por ejemplo, si seleccionas ImeAction.Next
o ImeAction.Previous
como el tipo de acción, de forma predeterminada, el enfoque se desplazará al campo de entrada posterior o anterior, respectivamente. De manera similar, un botón de acción configurado en ImeAction.Done
suele cerrar el teclado en pantalla. Estas funciones predeterminadas se ejecutan automáticamente y no requieren que proporciones un KeyboardActionHandler
.
Además de estas acciones predeterminadas, también puedes implementar un comportamiento personalizado.
Cuando proporcionas tu KeyboardActionHandler
, su método onKeyboardAction
recibe una función performDefaultAction
. Puedes llamar a esta
función performDefaultAction()
en cualquier momento dentro de tu lógica personalizada para activar también
el comportamiento predeterminado estándar asociado con la acción de IME actual.
TextField( state = textFieldViewModel.usernameState, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), onKeyboardAction = { performDefaultAction -> textFieldViewModel.validateUsername() performDefaultAction() } )
En este fragmento, se ilustra un caso de uso común en una pantalla de registro con un campo de nombre de usuario. Para este campo, se selecciona ImeAction.Next
por su botón de acción del teclado. Esta opción permite una navegación rápida y fluida al campo de contraseña posterior.
Además de esta navegación estándar, se requiere iniciar un proceso de validación en segundo plano para el nombre de usuario a medida que el usuario ingresa su contraseña. Para garantizar que el comportamiento predeterminado de cambio de enfoque inherente a ImeAction.Next
se retenga junto con esta lógica de validación personalizada, se invoca la función performDefaultAction()
. Llamar a performDefaultAction()
activa de forma implícita el sistema subyacente de administración de enfoque para mover el enfoque al siguiente elemento de IU apropiado, lo que preserva el flujo de navegación esperado.
Crea un campo de contraseña seguro
SecureTextField
es un elemento componible creado sobre campos de texto basados en el estado para escribir un campo de contraseña. Te recomendamos que uses SecureTextField
para crear
campos de texto de contraseñas, ya que oculta la entrada de caracteres de forma predeterminada y inhabilita las acciones de cortar
y copiar.
SecureTextField
tiene un textObfuscationMode
, que controla cómo el usuario ve la entrada de caracteres. textObfuscationMode
tiene las siguientes opciones:
Hidden
: Oculta toda la entrada. Es el comportamiento predeterminado en plataformas de computadoras.Visible
: Muestra toda la entrada.RevealLastTyped
: Oculta toda la entrada, excepto el último carácter. Comportamiento predeterminado en dispositivos móviles.
Recursos adicionales
- Cómo aplicar formato automáticamente a un número de teléfono en un campo de texto
- Cómo ocultar o mostrar la contraseña según un botón de activación del usuario
- Cómo validar la entrada a medida que el usuario escribe
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Cómo crear la arquitectura de tu IU de Compose
- El estado y Jetpack Compose
- Cómo guardar el estado de la IU en Compose