TextField
permet aux utilisateurs de saisir et de modifier du texte. Vous pouvez utiliser deux types de champs de texte: les champs de texte basés sur l'état et les champs de texte basés sur la valeur. Sélectionnez le type pour lequel vous souhaitez afficher du contenu:
Nous vous recommandons d'utiliser des champs de texte basés sur l'état, car ils offrent une approche plus complète et plus fiable pour gérer l'état d'un TextField
. Le tableau suivant présente les différences entre ces types de champs de texte et les principaux avantages des champs de texte basés sur l'état:
Fonctionnalité |
Champs de texte basés sur la valeur |
Champs de texte basés sur l'état |
Avantages liés à l'état |
---|---|---|---|
Gestion de l'état |
Met à jour l'état du champ de texte avec le rappel |
Utilise explicitement un objet |
|
Transformation visuelle |
Utilise |
Utilise |
|
Limites de lignes |
Accepte |
Utilise |
|
Champ de texte sécurisé |
N/A |
|
|
Cette page explique comment implémenter TextField
, styliser l'entrée TextField
et configurer d'autres options TextField
, telles que les options de clavier et la transformation visuelle de l'entrée utilisateur.
Choisir l'implémentation TextField
Il existe deux niveaux d'implémentation de TextField
:
TextField
est l'implémentation Material Design. Il s'agit de celle que nous recommandons, car elle respecte les consignes Material Design :BasicTextField
permet aux utilisateurs de modifier du texte à l'aide du clavier physique ou virtuel, mais ne fournit aucune décoration comme un indice ou un espace réservé.
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
OutlinedTextField( state = rememberTextFieldState(), label = { Text("Label") } )
Style TextField
TextField
et BasicTextField
partagent de nombreux paramètres communs pour la personnalisation.
La liste complète des éléments TextField
est disponible dans le code source TextField
. Voici une liste non exhaustive de quelques paramètres utiles:
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) )
Nous vous recommandons d'utiliser TextField
plutôt que BasicTextField
lorsque votre conception nécessite un élément Material TextField
ou OutlinedTextField
. Toutefois, vous devez utiliser BasicTextField
lorsque vous créez des conceptions qui n'ont pas besoin des décorations de la spécification Material.
Configurer les limites de ligne
Les composables TextField
sont compatibles avec le défilement sur un seul axe. Le comportement de défilement est déterminé par le paramètre lineLimits
. Les TextField
configurés pour une seule ligne défilent horizontalement, tandis que les TextField
multilignes défilent verticalement.
Utilisez TextFieldLineLimits
pour choisir la configuration de ligne appropriée pour votre TextField
:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine )
La configuration SingleLine
présente les caractéristiques suivantes:
- Le texte ne s'affiche jamais sur plusieurs lignes et ne permet pas d'ajouter de nouvelles lignes.
TextField
a toujours une hauteur fixe.- Si le texte déborde, il défile horizontalement.
TextField( state = rememberTextFieldState("Hello\nWorld\nHello\nWorld"), lineLimits = TextFieldLineLimits.MultiLine(1, 4) )
La configuration MultiLine
présente les caractéristiques suivantes:
- Accepte deux paramètres:
minHeightInLines
etmaxHeightInLines
. - La hauteur du champ de texte est d'au moins
minHeightInLines
. - Si le texte déborde, il sera mis en retour à la ligne.
- Si le texte nécessite plus de lignes, le champ se développe jusqu'à atteindre une hauteur de
maxHeightInLines
et défile verticalement.
Mettre en forme la saisie avec l'API Brush
Vous pouvez utiliser l'API Brush pour créer des styles plus avancés dans votre TextField
.
La section suivante explique comment utiliser un pinceau pour ajouter un dégradé de couleur à l'entrée TextField
.
Pour en savoir plus sur l'utilisation de l'API Brush pour styliser le texte, consultez la section Activer le style avancé avec l'API Brush.
Implémenter des dégradés de couleurs à l'aide de TextStyle
Pour implémenter un dégradé de couleur lorsque vous saisissez du texte dans un TextField
, définissez le pinceau de votre choix en tant que TextStyle
pour votre TextField
. Dans cet exemple, nous utilisons un pinceau intégré avec un linearGradient
pour afficher l'effet de dégradé arc-en-ciel lorsque du texte est saisi dans le 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
.Gérer l'état du champ de texte
TextField
utilise une classe de conteneur d'état dédiée appelée TextFieldState
pour son contenu et sa sélection actuelle. TextFieldState
est conçu pour être hissé partout où il s'intègre dans votre architecture. TextFieldState
fournit deux propriétés principales:
initialText
: contenu duTextField
.initialSelection
: indique l'emplacement actuel du curseur ou de la sélection.
Ce qui différencie TextFieldState
des autres approches, comme le rappel onValueChange
, est que TextFieldState
encapsule entièrement l'ensemble du flux d'entrée. Cela inclut l'utilisation des structures de données de support appropriées, l'intégration de filtres et de formatseurs, ainsi que la synchronisation de toutes les modifications provenant de différentes sources.
Vous pouvez utiliser TextFieldState()
pour hisser l'état dans TextField
. Pour ce faire, nous vous recommandons d'utiliser la fonction rememberTextFieldState()
.
rememberTextFieldState()
crée l'instance TextFieldState
dans votre composable, s'assure que l'objet d'état est mémorisé et fournit une fonctionnalité d'enregistrement et de restauration intégrée:
val usernameState = rememberTextFieldState() TextField( state = usernameState, lineLimits = TextFieldLineLimits.SingleLine, placeholder = { Text("Enter Username") } )
rememberTextFieldState
peut avoir un paramètre vide ou une valeur initiale transmise pour représenter la valeur du texte lors de l'initialisation. Si une valeur différente est transmise lors d'une recomposition ultérieure, la valeur de l'état n'est pas mise à jour. Pour mettre à jour l'état après son initialisation, appelez les méthodes de modification sur TextFieldState
.
TextField( state = rememberTextFieldState(initialText = "Username"), lineLimits = TextFieldLineLimits.SingleLine, )

TextField
avec le texte initial "Nom d'utilisateur".Modifier le texte avec TextFieldBuffer
Un TextFieldBuffer
sert de conteneur de texte modifiable, semblable à un StringBuilder
. Il contient à la fois le contenu textuel et des informations sur la sélection actuelle.
Vous rencontrez souvent TextFieldBuffer
comme champ d'application du récepteur sur des fonctions telles que TextFieldState.edit
, InputTransformation.transformInput
ou OutputTransformation.transformOutput
. Dans ces fonctions, vous pouvez lire ou modifier le TextFieldBuffer
si nécessaire. Ensuite, ces modifications sont soit validées dans TextFieldState
, soit transmises au pipeline de rendu dans le cas de OutputTransformation
.
Vous pouvez utiliser des fonctions de modification standards telles que append
, insert
, replace
ou delete
pour modifier le contenu du tampon. Pour modifier l'état de sélection, définissez directement sa variable selection: TextRange
ou utilisez des fonctions utilitaires telles que placeCursorAtEnd
ou selectAll
. La sélection elle-même est représentée par un TextRange
, où l'indice de début est inclusif et l'indice de fin est exclusif.
Un TextRange
avec des valeurs de début et de fin identiques, comme (3, 3)
, indique une position du curseur sans caractère actuellement sélectionné.
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, "-") } )
Modifier le texte dans TextFieldState
Il existe plusieurs méthodes qui vous permettent de modifier l'état directement via votre variable d'état:
edit
: vous permet de modifier le contenu de l'état et vous fournit des fonctionsTextFieldBuffer
afin que vous puissiez utiliser des méthodes telles queinsert
,replace
,append
, etc.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
: efface le texte actuel, le remplace par le texte donné et définit le curseur à la fin.usernameState.setTextAndPlaceCursorAtEnd("I really love Android") // textFieldState.text : I really love Android // textFieldState.selection : TextRange(21, 21)
clearText
: efface tout le texte.usernameState.clearText() // textFieldState.text : // textFieldState.selection : TextRange(0, 0)
Pour en savoir plus sur les autres fonctions TextFieldState
, consultez la documentation de référence sur TextFieldState
.
Modifier l'entrée utilisateur
Les sections suivantes expliquent comment modifier la saisie utilisateur.
La transformation d'entrée vous permet de filtrer l'entrée TextField
pendant que l'utilisateur saisit du texte, tandis que la transformation de sortie met en forme l'entrée de l'utilisateur avant qu'elle ne s'affiche à l'écran.
Filtrer la saisie utilisateur à l'aide de transformations d'entrée
Une transformation d'entrée vous permet de filtrer les entrées de l'utilisateur. Par exemple, si votre TextField
accepte un numéro de téléphone américain, vous ne souhaitez accepter que 10 chiffres. Les résultats de InputTransformation
sont enregistrés dans TextFieldState
.
Des filtres intégrés sont disponibles pour les cas d'utilisation courants de InputTransformation
. Pour limiter la longueur, appelez InputTransformation.maxLength()
:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine, inputTransformation = InputTransformation.maxLength(10) )
Transformations de saisie personnalisées
InputTransformation
est une interface de fonction unique. Lorsque vous implémentez votre InputTransformation
personnalisée, vous devez remplacer TextFieldBuffer.transformInput
:
class CustomInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { } }
Pour un numéro de téléphone, ajoutez une transformation d'entrée personnalisée qui n'autorise que la saisie de chiffres dans le TextField
:
class DigitOnlyInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { if (!TextUtils.isDigitsOnly(asCharSequence())) { revertAllChanges() } } }
Chaîner des transformations d'entrée
Pour ajouter plusieurs filtres à votre saisie de texte, enchaînez des InputTransformation
à l'aide de la fonction d'extension then
. Les filtres sont exécutés de manière séquentielle. Nous vous recommandons d'appliquer d'abord les filtres les plus sélectifs afin d'éviter les transformations inutiles sur les données qui seront finalement filtrées.
TextField( state = rememberTextFieldState(), inputTransformation = InputTransformation.maxLength(6) .then(CustomInputTransformation()), )
Après avoir ajouté des transformations d'entrée, l'entrée TextField
accepte 10 chiffres maximum.
Mettre en forme les données avant leur affichage
Les OutputTransformation
vous permettent de mettre en forme la saisie utilisateur avant qu'elle ne soit affichée à l'écran. Contrairement à InputTransformation
, la mise en forme effectuée via OutputTransformation
n'est pas enregistrée dans TextFieldState
. En vous appuyant sur l'exemple de numéro de téléphone précédent, vous devez ajouter des parenthèses et des tirets aux endroits appropriés:

Il s'agit de la nouvelle méthode de gestion des VisualTransformation
dans les TextField
basées sur la valeur, avec une différence clé : vous n'avez pas à calculer leurs mappages de décalage.
OutputTransformation
est une interface de méthode abstraite unique. Pour implémenter un OutputTransformation
personnalisé, vous devez remplacer la méthode transformOutput
:
class CustomOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { } }
Pour mettre en forme un numéro de téléphone, ajoutez une parenthèse ouvrante à l'index 0, une parenthèse fermante à l'index 4 et un tiret à l'index 8 à votre OutputTransformation
:
class PhoneNumberOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { if (length > 0) insert(0, "(") if (length > 4) insert(4, ")") if (length > 8) insert(8, "-") } }
Ajoutez ensuite votre OutputTransformation
à TextField
:
TextField( state = rememberTextFieldState(), outputTransformation = PhoneNumberOutputTransformation() )
Fonctionnement des transformations
Le schéma suivant montre le flux de l'entrée de texte à la transformation en sortie:

- La source d'entrée reçoit une entrée.
- L'entrée est filtrée via un
InputTransformation
, qui est enregistré dans TextFieldState. - L'entrée est transmise via un
OutputTransformation
pour le formatage. - L'entrée est présentée dans
TextField
.
Définir les options de clavier
TextField
vous permet de définir des options de configuration du clavier, telles que la disposition des touches, ou d'activer la correction automatique si le clavier le permet. Certaines options ne sont pas garanties si le clavier logiciel ne respecte pas les options fournies ici. Voici la liste des options de clavier compatibles:
capitalization
autoCorrect
keyboardType
imeAction
La classe KeyboardOptions
inclut désormais un nouveau paramètre booléen, showKeyboardOnFocus
, que vous utilisez spécifiquement pour les composants TextField
intégrés à TextFieldState
. Cette option régit le comportement du clavier logiciel lorsque le TextField
acquiert le focus par d'autres moyens que l'interaction directe de l'utilisateur (par exemple, de manière programmatique).
Lorsque KeyboardOptions.showKeyboardOnFocus
est défini sur "true", le clavier logiciel n'apparaît pas automatiquement si TextField
reçoit le focus indirectement. Dans ce cas, l'utilisateur doit appuyer explicitement sur le TextField
lui-même pour afficher le clavier.
Définir la logique d'interaction au clavier
Le bouton d'action du clavier logiciel Android permet d'obtenir des réponses interactives dans votre application. Pour en savoir plus sur la configuration du bouton d'action, consultez la section Définir les options du clavier.

Pour définir ce qui se passe lorsqu'un utilisateur appuie sur ce bouton d'action, utilisez le paramètre onKeyboardAction
. Ce paramètre accepte une interface fonctionnelle facultative appelée KeyboardActionHandler
. L'interface KeyboardActionHandler
ne contient qu'une seule méthode, onKeyboardAction(performDefaultAction: () -> Unit)
.
En fournissant une implémentation pour cette méthode onKeyboardAction
, vous pouvez introduire une logique personnalisée qui s'exécute lorsqu'un utilisateur appuie sur le bouton d'action du clavier.
Plusieurs types d'actions de clavier standards sont associés à des comportements par défaut intégrés.
Par exemple, si vous sélectionnez ImeAction.Next
ou ImeAction.Previous
comme type d'action, le focus sera placé par défaut sur le champ de saisie suivant ou précédent, respectivement. De même, un bouton d'action défini sur ImeAction.Done
ferme généralement le clavier logiciel. Ces fonctionnalités par défaut sont exécutées automatiquement et ne nécessitent pas de fournir de KeyboardActionHandler
.
Vous pouvez également implémenter un comportement personnalisé en plus de ces actions par défaut.
Lorsque vous fournissez votre KeyboardActionHandler
, sa méthode onKeyboardAction
reçoit une fonction performDefaultAction
. Vous pouvez appeler cette fonction performDefaultAction()
à tout moment dans votre logique personnalisée pour également déclencher le comportement par défaut standard associé à l'action IME actuelle.
TextField( state = textFieldViewModel.usernameState, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), onKeyboardAction = { performDefaultAction -> textFieldViewModel.validateUsername() performDefaultAction() } )
Cet extrait illustre un cas d'utilisation courant sur un écran d'enregistrement comportant un champ de nom d'utilisateur. Pour ce champ, ImeAction.Next
est sélectionné pour le bouton d'action du clavier. Ce choix permet une navigation rapide et fluide vers le champ de mot de passe suivant.
En plus de cette navigation standard, vous devez lancer un processus de validation en arrière-plan pour le nom d'utilisateur lorsque l'utilisateur saisit son mot de passe. Pour vous assurer que le comportement de changement de focus par défaut inhérent à ImeAction.Next
est conservé avec cette logique de validation personnalisée, la fonction performDefaultAction()
est appelée. L'appel de performDefaultAction()
déclenche implicitement le système de gestion du focus sous-jacent pour déplacer le focus vers l'élément d'interface utilisateur suivant approprié, en préservant le flux de navigation attendu.
Créer un champ de mot de passe sécurisé
SecureTextField
est un composable basé sur des champs de texte basés sur l'état pour écrire un champ de mot de passe. Nous vous recommandons d'utiliser SecureTextField
pour créer des champs de texte de mot de passe, car il masque la saisie de caractères par défaut et désactive les actions de découpage et de copie.
SecureTextField
possède un textObfuscationMode
, qui contrôle la façon dont l'utilisateur voit la saisie de caractères. textObfuscationMode
propose les options suivantes:
Hidden
: masque toutes les entrées. Comportement par défaut sur les plates-formes de bureau.Visible
: affiche toutes les entrées.RevealLastTyped
: masque toutes les entrées, à l'exception du dernier caractère. Comportement par défaut sur les appareils mobiles.
Ressources supplémentaires
- Mettre en forme automatiquement un numéro de téléphone dans un champ de texte
- Afficher ou masquer le mot de passe en fonction d'un bouton d'activation/de désactivation de l'utilisateur
- Valider la saisie à mesure que l'utilisateur saisit du texte
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Structurer votre interface utilisateur Compose
- États et Jetpack Compose
- Enregistrer l'état de l'UI dans Compose