Gérer les entrées utilisateur

TextField permet aux utilisateurs de saisir et de modifier du texte. Cette page explique comment implémenter TextField, styliser la saisie TextField et configurer d'autres options TextField, telles que les options du clavier et la transformation visuelle de l'entrée utilisateur.

Choisir l'implémentation TextField

Il existe deux niveaux d'implémentation de TextField:

  1. TextField est l'implémentation Material Design. Nous vous recommandons de choisir cette implémentation, car elle respecte les consignes Material Design :
    • Le style par défaut est rempli.
    • OutlinedTextField correspond à la version de style contour.
  2. 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é.

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

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

Un champ de texte modifiable contenant le mot

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

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

Champ de texte modifiable avec une bordure et un libellé violets

Style TextField

TextField et BasicTextField partagent de nombreux paramètres communs pour leur personnalisation. La liste complète des TextField est disponible dans le code source TextField. Voici une liste de quelques paramètres utiles :

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

Champ de texte multiligne, avec deux lignes modifiables et le libellé

Nous vous recommandons d'utiliser TextField plutôt que BasicTextField lorsque votre conception nécessite un élément Material TextField ou OutlineTextField. Toutefois, vous devez utiliser BasicTextField lorsque vous créez des conceptions qui n'ont pas besoin des décorations spécifiées dans la spécification Material.

Appliquer un style à la saisie avec l'API Brush

Vous pouvez utiliser l'API Brush pour appliquer un style plus avancé à 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 Activer la stylisation avancée avec l'API Brush.

Implémenter des dégradés de couleur à l'aide de TextStyle

Pour implémenter un dégradé de couleurs lorsque vous saisissez du texte dans un élément TextField, définissez le pinceau de votre choix en tant que TextStyle pour l'élément TextField. Dans cet exemple, nous utilisons un pinceau intégré avec un linearGradient pour afficher l'effet de dégradé arc-en-ciel à mesure que du texte est saisi dans TextField.

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

Utiliser buildAnnotatedString, SpanStyle et linearGradient pour ne personnaliser qu'une partie de texte.
Figure 3. Utilisation de buildAnnotatedString et SpanStyle, avec linearGradient, pour personnaliser uniquement une portion de texte.

Définir les options du 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

Mettre en forme la saisie

TextField vous permet de définir un élément VisualTransformation au niveau de la valeur d'entrée. Par exemple, vous pouvez remplacer les caractères par * pour les mots de passe ou insérer des traits d'union tous les 4 chiffres dans le cas d'un numéro de carte de paiement :

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

Champ de saisie du mot de passe, avec le texte masqué

D'autres exemples sont disponibles dans le code source de VisualTransformationSamples.

Effacer la saisie

Une tâche courante lors de la modification de texte consiste à supprimer les caractères de début ou à transformer la chaîne d'entrée chaque fois qu'elle change.

Partez du principe que le clavier peut apporter des modifications arbitraires et importantes à chaque onValueChange. Cela peut se produire, par exemple, si l'utilisateur a recours à la correction automatique, remplace un mot par un emoji ou exploite d'autres fonctionnalités de retouche intelligentes. Pour gérer ce comportement correctement, écrivez une logique de transformation selon laquelle le texte actuel transmis à onValueChange n'a aucun rapport avec les valeurs précédentes ou suivantes transmises à onValueChange.

Pour implémenter un champ de texte qui empêche les zéros au début, vous pouvez implémenter la suppression de tous les zéros au début d'une chaîne à chaque changement de valeur.

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

Pour contrôler la position du curseur lors du nettoyage du texte, utilisez la surcharge TextFieldValue de TextField dans le cadre de l'état.

Bonnes pratiques concernant l'état

Vous trouverez ci-dessous une série de bonnes pratiques pour définir et mettre à jour l'état TextField afin d'éviter les problèmes de saisie dans votre application.

  • Utilisez MutableState pour représenter l'état TextField: évitez d'utiliser des flux réactifs tels que StateFlow pour représenter l'état TextField, car ces structures peuvent entraîner des retards asynchrones.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Évitez les retards pour mettre à jour l'état: lorsque vous appelez onValueChange, mettez à jour votre TextField de manière synchrone et immédiate:

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

  • Où définir l'état: si l'état TextField nécessite des validations de logique métier lors de la saisie, il est correct de hisser l'état dans votre ViewModel. Si ce n'est pas le cas, vous pouvez utiliser des composables ou une classe de conteneur d'état comme source fiable. Pour savoir où hisser votre état, consultez la documentation sur le hissage d'état.