Texte dans Compose

Le texte est un élément central de n'importe quelle interface utilisateur. Jetpack Compose facilite l'affichage ou l'écriture de texte. Il exploite la composition de ses principaux composants. De la sorte, vous n'avez pas besoin de remplacer les propriétés et les méthodes, ni d'étendre les classes de grande taille pour disposer d'une logique et d'une conception de composable spécifiques qui fonctionnent comme vous le souhaitez.

À la base, Compose fournit BasicText et BasicTextField, qui sont les éléments clés permettant d'afficher le texte et de gérer les entrées utilisateur. À un niveau supérieur, Compose fournit Text et TextField, qui sont des composables conformes aux consignes Material Design. Nous vous recommandons de les utiliser, car ils s'adaptent à l'apparence attendue par vos utilisateurs sur Android. De plus, ils incluent d'autres options qui simplifient leur personnalisation tout en limitant les efforts de codage.

Affichage du texte

La manière la plus simple d'afficher du texte consiste à utiliser le composable Text avec l'argument String :

@Composable
fun SimpleText() {
    Text("Hello World")
}

"Hello World" en texte brut

Afficher le texte de la ressource

Nous vous recommandons d'utiliser des ressources de chaîne au lieu de coder en dur les valeurs Text. De cette manière, vous pouvez partager les mêmes chaînes avec vos vues Android et préparer votre application pour l'internationalisation :

@Composable
fun StringResourceText() {
    Text(stringResource(R.string.hello_world))
}

Appliquer un style à du texte

Le composable Text comporte plusieurs paramètres facultatifs pour styliser son contenu. Vous trouverez ci-dessous la liste des paramètres qui couvrent la plupart des cas d'utilisation courants liés au texte. Pour afficher tous les paramètres de Text, nous vous recommandons de consulter le code source de Compose Text.

Lorsque vous définissez l'un de ces paramètres, vous appliquez le style à l'ensemble de la valeur de texte. Si vous devez appliquer plusieurs styles dans la même ligne ou les mêmes paragraphes, découvrez comment intégrer plusieurs styles.

Modifier la couleur du texte

@Composable
fun BlueText() {
    Text("Hello World", color = Color.Blue)
}

Texte "Hello World" affiché en bleu

Modifier la taille du texte

@Composable
fun BigText() {
  Text("Hello World", fontSize = 30.sp)
}

Texte "Hello World" affiché en plus grand

Mettre le texte en italique

Utilisez le paramètre fontStyle pour mettre du texte en italique (ou définissez un autre style de police avec FontStyle).

@Composable
fun ItalicText() {
  Text("Hello World", fontStyle = FontStyle.Italic)
}

Texte "Hello World" en italique

Mettre le texte en gras

Utilisez le paramètre fontWeight pour mettre du texte en gras (ou définissez une autre épaisseur de police avec FontWeight).

@Composable
fun BoldText() {
    Text("Hello World", fontWeight = FontWeight.Bold)
}

Texte "Hello World" en gras

Alignements de texte

Le paramètre textAlign permet de définir l'alignement du texte dans une zone modulable Text.

Par défaut, Text sélectionne l'alignement de texte naturel en fonction de la valeur de son contenu :

  • Bord gauche du conteneur Text pour les alphabets de gauche à droite tels que le latin, le cyrillique ou le hangûl
  • Bord droit du conteneur Text pour les alphabets de droite à gauche tels que l'arabe ou l'hébreu
@Preview(showBackground = true)
@Composable
fun CenterText() {
    Text("Hello World", textAlign = TextAlign.Center,
                modifier = Modifier.width(150.dp))
}

Texte "Hello World" centré dans l'élément conteneur

Si vous souhaitez définir manuellement l'alignement du texte d'un composable Text, préférez TextAlign.Start et TextAlign.End au lieu de TextAlign.Left et TextAlign.Right respectivement, car ils définissent le côté approprié du composable Text en fonction de l'orientation du texte de la langue préférée. Par exemple, TextAlign.End aligne le texte français vers la droite et le texte arabe vers la gauche, mais TextAlign.Right aligne le texte vers la droite, quel que soit l'alphabet utilisé.

Ombre

Le paramètre style permet de définir un objet de type TextStyle et de configurer plusieurs paramètres tels que l'ombre. Shadow reçoit une couleur pour l'ombre, le décalage (ou l'emplacement où elle se trouve par rapport à l'élément Text) et le rayon de floutage, qui détermine le niveau de floutage de l'ombre.

@Preview(showBackground = true)
@Composable
fun TextShadow() {
    val offset = Offset(5.0f, 10.0f)
    Text(
        text = "Hello world!",
        style = TextStyle(
            fontSize = 24.sp,
            shadow = Shadow(
                color = Color.Blue,
                offset = offset,
                blurRadius = 3f
            )
        )
    )
}

Texte "Hello World" avec une ombre bleue

Gestion des polices

Text utilise un paramètre fontFamily pour définir la police utilisée dans le composable. Par défaut, les familles de polices serif, sans-serif, monospace et cursive sont incluses :

@Composable
fun DifferentFonts() {
    Column {
        Text("Hello World", fontFamily = FontFamily.Serif)
        Text("Hello World", fontFamily = FontFamily.SansSerif)
    }
}

Texte "Hello World" dans deux polices : serif et sans-serif

L'attribut fontFamily permet d'utiliser les polices personnalisées définies dans le dossier res/font :

font dans l'environnement de développement " class="l10n-absolute-url-src screenshot" l10n-attrs-original-order="src,alt,width,class" src="https://developer.android.com/static/images/jetpack/compose/text-font-folder.png" width="400" />

Cet exemple montre comment définir une propriété fontFamily en fonction de ces fichiers de polices et en utilisant la fonction Font :

val firaSansFamily = FontFamily(
        Font(R.font.firasans_light, FontWeight.Light),
        Font(R.font.firasans_regular, FontWeight.Normal),
        Font(R.font.firasans_italic, FontWeight.Normal, FontStyle.Italic),
        Font(R.font.firasans_medium, FontWeight.Medium),
        Font(R.font.firasans_bold, FontWeight.Bold)
)

Enfin, vous pouvez transmettre cet attribut fontFamily au composable Text. Étant donné qu'un élément fontFamily peut inclure différentes épaisseurs de police, vous pouvez spécifier fontWeight manuellement afin de sélectionner celle qui convient au texte :

Column {
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Light)
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Normal)
    Text(
        ..., fontFamily = firaSansFamily, fontWeight = FontWeight.Normal,
        fontStyle = FontStyle.Italic
    )
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Medium)
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Bold)
}

Texte "Hello World" dans différents styles et épaisseurs de police

Pour découvrir comment définir la typographie dans l'ensemble de votre application, consultez la documentation sur les thèmes.

Plusieurs styles dans un texte

Pour définir différents styles dans le même composable Text, vous devez utiliser AnnotatedString, chaîne pouvant être annotée avec des styles d'annotations arbitraires.

AnnotatedString est une classe de données contenant les éléments suivants :

  • Une valeur Text
  • Une List de SpanStyleRange, qui équivaut au style intégré avec une plage de positions dans la valeur de texte
  • Une List de ParagraphStyleRange, spécifiant l'alignement, la direction, la hauteur et le style du retrait du texte

TextStyle est destiné au composable Text, tandis que SpanStyle et ParagraphStyle sont destinés à être utilisés dans AnnotatedString.

La différence entre SpanStyle et ParagraphStyle est que ParagraphStyle peut être appliqué à un paragraphe entier, tandis que SpanStyle peut être appliqué au niveau des caractères. Une fois qu'une partie du texte est marquée d'une annotation ParagraphStyle, elle est séparée du reste du texte, comme des sauts de ligne avaient été ajoutés au début et à la fin.

AnnotatedString dispose d'un compilateur de sûreté du typage pour faciliter la création : buildAnnotatedString.

@Composable
fun MultipleStylesInText() {
    Text(
        buildAnnotatedString {
            withStyle(style = SpanStyle(color = Color.Blue)) {
                append("H")
            }
            append("ello ")

            withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Red)) {
                append("W")
            }
            append("orld")
        }
    )
}

Texte "Hello World" avec plusieurs modifications de style intégrées (la lettre H est en bleu, et le W est en rouge et en gras)

Nous pouvons définir ParagraphStyle de la même manière :

@Composable
fun ParagraphStyle() {
    Text(
        buildAnnotatedString {
            withStyle(style = ParagraphStyle(lineHeight = 30.sp)) {
                withStyle(style = SpanStyle(color = Color.Blue)) {
                    append("Hello\n")
                }
                withStyle(
                    style = SpanStyle(
                        fontWeight = FontWeight.Bold,
                        color = Color.Red
                    )
                ) {
                    append("World\n")
                }
                append("Compose")
            }
        }
    )
}

Trois paragraphes dans trois styles différents : bleu, rouge et gras, noir uni

Nombre maximal de lignes

Pour limiter le nombre de lignes visibles dans un composable Text, définissez le paramètre maxLines :

@Composable
fun LongText() {
    Text("hello ".repeat(50), maxLines = 2)
}

Long passage de texte tronqué après deux lignes

Débordement de texte

Lorsque vous limitez un texte long, vous pouvez indiquer un TextOverflow, qui n'intervient que si le texte affiché est tronqué. Pour ce faire, définissez le paramètre textOverflow :

@Composable
fun OverflowedText() {
    Text("Hello Compose ".repeat(50), maxLines = 2, overflow = TextOverflow.Ellipsis)
}

Long passage de texte tronqué après trois lignes, avec une ellipse à la fin

API includeFontPadding et lineHeight

includeFontPadding est une ancienne propriété qui ajoute une marge intérieure basée sur les métriques de police en haut de la première ligne et en bas de la dernière ligne d'un texte. Dans Compose 1.2.0, includeFontPadding est défini sur true par défaut.

Nous vous recommandons de définir includeFontPadding sur false (ce qui supprimera la marge intérieure supplémentaire) à l'aide de l'API expérimentale/obsolète PlatformTextStyle dans Compose 1.2.0 et d'ajuster le texte si nécessaire.

@Composable
fun AlignedText() {
    Text(
        text = myText,
        style = LocalTextStyle.current.merge(
            TextStyle(
                lineHeight = 2.5.em,
                platformStyle = PlatformTextStyle(
                    includeFontPadding = false
                ),
                lineHeightStyle = LineHeightStyle(
                    alignment = LineHeightStyle.Alignment.Center,
                    trim = LineHeightStyle.Trim.None
                )
            )
        )
    )
}

Dans les prochaines versions de Compose, includeFontPadding sera défini par défaut sur false, et l'API PlatformTextStyle sera supprimée.

Pour en savoir plus sur le contexte de cette modification, sur le fonctionnement de includeFontPadding dans le système de vues et sur les modifications que nous avons apportées pour Compose et les nouvelles API LineHeightStyle, consultez cet article de blog.

Personnalisation des thèmes

Si vous souhaitez utiliser le thème de l'application pour le style du texte, consultez cette documentation.

Interactions utilisateur

Jetpack Compose permet une interactivité ultraprécise dans Text. La sélection de texte est désormais plus flexible et peut être effectuée sur différentes mises en page modulables. Les interactions utilisateur dans le texte sont différentes des autres mises en page modulables, car vous ne pouvez pas ajouter de modificateur à une partie d'un composable Text. Cette section présente les différentes API permettant les interactions utilisateur.

Sélectionner du texte

Par défaut, les composables ne sont pas sélectionnables. Par conséquent, les utilisateurs ne peuvent pas sélectionner ni copier du texte depuis votre application. Pour activer la sélection de texte, vous devez encapsuler vos éléments de texte avec un composable SelectionContainer :

@Composable
fun SelectableText() {
    SelectionContainer {
        Text("This text is selectable")
    }
}

Court passage de texte sélectionné par l'utilisateur

Vous pouvez désactiver la sélection à des endroits spécifiques d'une zone sélectionnable. Pour ce faire, vous devez encapsuler l'emplacement non sélectionnable avec un composable DisableSelection :

@Composable
fun PartiallySelectableText() {
    SelectionContainer {
        Column {
            Text("This text is selectable")
            Text("This one too")
            Text("This one as well")
            DisableSelection {
                Text("But not this one")
                Text("Neither this one")
            }
            Text("But again, you can select this one")
            Text("And this one too")
        }
    }
}

Long passage de texte. L'utilisateur a essayé de sélectionner l'intégralité du passage, mais deux lignes n'ont pas été sélectionnées, car le composable DisableSelection leur est appliqué.

Déterminer la position d'un clic sur du texte

Pour écouter les clics sur Text, vous pouvez ajouter le modificateur clickable. Toutefois, si vous souhaitez déterminer la position d'un clic dans un composable Text dans le cas où vous effectuez différentes actions en fonction des différentes parties du texte, vous devez utiliser ClickableText à la place :

@Composable
fun SimpleClickableText() {
    ClickableText(
        text = AnnotatedString("Click Me"),
        onClick = { offset ->
            Log.d("ClickableText", "$offset -th character is clicked.")
        }
    )
}

Clic avec annotation

Lorsqu'un utilisateur clique sur un composable Text, vous pouvez joindre des informations supplémentaires à une partie de la valeur Text, comme une URL associée à un mot spécifique à ouvrir dans un navigateur. Pour ce faire, vous devez joindre une annotation, qui utilise une balise (String), un élément (String) et une plage de texte en tant que paramètres. Avec AnnotatedString, ces annotations peuvent être filtrées par leurs balises ou plages de texte. Voici un exemple :

@Composable
fun AnnotatedClickableText() {
    val annotatedText = buildAnnotatedString {
        append("Click ")

        // We attach this *URL* annotation to the following content
        // until `pop()` is called
        pushStringAnnotation(tag = "URL",
                             annotation = "https://developer.android.com")
        withStyle(style = SpanStyle(color = Color.Blue,
                                    fontWeight = FontWeight.Bold)) {
            append("here")
        }

        pop()
    }

    ClickableText(
        text = annotatedText,
        onClick = { offset ->
            // We check if there is an *URL* annotation attached to the text
            // at the clicked position
            annotatedText.getStringAnnotations(tag = "URL", start = offset,
                                                    end = offset)
                .firstOrNull()?.let { annotation ->
                    // If yes, we log its value
                    Log.d("Clicked URL", annotation.item)
                }
        }
    )
}

Saisir et modifier du texte

TextField permet aux utilisateurs de saisir et de modifier du texte. Il existe deux niveaux d'implémentation de TextField :

  1. TextField est l'implémentation Material Design. Il s'agit de celle que nous recommandons, 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") }
    )
}

Champ de texte modifiable contenant le mot "Hello" Champ comportant le libellé non modifiable "label"

@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

Appliquer un style à un champ de texte

TextField et BasicTextField partagent de nombreux paramètres communs pour leur personnalisation. La liste complète des éléments 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 de la spécification Material.

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

Mise en forme

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 VisualTransformSamples.

Nettoyage de la chaîne d'entrée

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.

Polices téléchargeables

À partir de Compose 1.2-alpha07, vous pouvez utiliser l'API de polices téléchargeables de l'application Compose pour télécharger des polices Google de manière asynchrone et les utiliser dans votre application.

Les polices téléchargeables basées sur des fournisseurs personnalisés ne sont pas disponibles pour le moment.

Utiliser des polices téléchargeables par programmation

Pour télécharger une police par programmation à partir de votre application, procédez comme suit :

  1. Ajoutez la dépendance :

    Groovy

    dependencies {
        ...
        implementation "androidx.compose.ui:ui-text-google-fonts:1.2.1"
    }
    

    Kotlin

    dependencies {
        ...
        implementation("androidx.compose.ui:ui-text-google-fonts:1.2.1")
    }
  2. Initialisez GoogleFont.Provider avec les identifiants pour Google Fonts.
    @OptIn(ExperimentalTextApi::class)
    val provider = GoogleFont.Provider(
       providerAuthority = "com.google.android.gms.fonts",
       providerPackage = "com.google.android.gms",
       certificates = R.array.com_google_android_gms_fonts_certs
    )
    
    Voici les paramètres reçus par le fournisseur :
    • Autorité du fournisseur de polices pour Google Fonts.
    • Package du fournisseur de polices permettant de vérifier l'identité du fournisseur.
    • Liste d'ensembles de hachages des certificats permettant de vérifier l'identité du fournisseur. Vous trouverez les hachages requis pour le fournisseur Google Fonts dans le fichier font_certs.xml de l'application exemple JetChat.
    Notez que vous devez ajouter l'annotation ExperimentalTextApi pour pouvoir utiliser les API de polices téléchargeables dans votre application.
  3. Définissez une famille de polices, FontFamily, comme suit :
    import androidx.compose.ui.text.googlefonts.GoogleFont
    import androidx.compose.ui.text.font.FontFamily
    import androidx.compose.ui.text.googlefonts.Font
    
    val fontName = GoogleFont("Lobster Two")
    
    val fontFamily = FontFamily(
       Font(googleFont = fontName, fontProvider = provider)
    )
    
    Vous pouvez interroger d'autres paramètres de police tels que l'épaisseur et le style avec, respectivement, FontWeight et FontStyle :
    import androidx.compose.ui.text.googlefonts.GoogleFont
    import androidx.compose.ui.text.font.FontFamily
    import androidx.compose.ui.text.googlefonts.Font
    
    val fontName = GoogleFont("Lobster Two")
    
    val fontFamily = FontFamily(
       Font(googleFont = fontName, fontProvider = provider,
            weight = FontWeight.Bold, style = FontStyle.Italic)
    )
    
  4. Configurez la famille de polices (FontFamily) à utiliser dans la fonction modulable Text. Et le tour est joué !
    Text(
        fontFamily = fontFamily,
        text = "Hello World!"
    )
    
    Vous pouvez également définir une typographie pour utiliser votre FontFamily.
    val MyTypography = Typography(
       body1 = TextStyle(
       fontFamily = fontFamily,
       fontWeight = FontWeight.Normal,
       fontSize = ...
    ),
       body2 = TextStyle(
       fontFamily = fontFamily,
       fontWeight = FontWeight.Bold,
       letterSpacing = ...
    ),
       h4 = TextStyle(
       fontFamily = fontFamily,
       fontWeight = FontWeight.SemiBold
       ...
    ),
    ...
    
    Définissez ensuite cette typographie sur le thème de votre application :
    MyAppTheme(
       typography = MyTypography
    ) {
    ...
    

Pour obtenir un exemple d'application mettant en œuvre des polices téléchargeables dans Compose avec Material3, veillez à consulter l'application exemple JetChat.

Polices de remplacement

Vous pouvez déterminer une série de polices de remplacement au cas où celle que vous avez spécifiée ne se téléchargerait pas correctement. Par exemple, si votre police téléchargeable est définie comme suit :

import androidx.compose.ui.text.googlefonts.Font

val fontName = GoogleFont("Lobster Two")

val fontFamily = FontFamily(
   Font(googleFont = fontName, fontProvider = provider),
   Font(googleFont = fontName, fontProvider = provider, weight = FontWeight.Bold)
)

Vous pouvez définir les valeurs par défaut de votre police pour les deux épaisseurs, comme suit :

import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.googlefonts.Font

val fontName = GoogleFont("Lobster Two")

val fontFamily = FontFamily(
   Font(googleFont = fontName, fontProvider = provider),
   Font(resId = R.font.my_font_regular),
   Font(googleFont = fontName, fontProvider = provider, weight = FontWeight.Bold),
   Font(resId = R.font.my_font_regular_bold, weight = FontWeight.Bold)
)

Veillez à ajouter les importations appropriées.

En définissant FontFamily de la sorte, vous créez une famille de polices (FontFamily) contenant deux chaînes, une pour chaque épaisseur de police. Le mécanisme de chargement tente d'abord de récupérer la police en ligne, puis la police située dans le dossier de ressources R.font local.

Déboguer votre implémentation

Pour vous aider à vérifier si la police est téléchargée correctement, vous pouvez définir un gestionnaire de coroutine de débogage. Le handle identifiera le comportement à suivre en cas d'échec du chargement asynchrone de la police.

Commencez par créer un CoroutineExceptionHandler.

val handler = CoroutineExceptionHandler { _, throwable ->
   // process the Throwable
   Log.e(TAG, "There has been an issue: ", throwable)
}

Transmettez-le ensuite à la méthode createFontFamilyResolver pour que le résolveur utilise le nouveau gestionnaire :

CompositionLocalProvider(
        LocalFontFamilyResolver provides createFontFamilyResolver(LocalContext.current, handler)
    ) {
        Column {
            Text(
                text = "Hello World!",
                style = MaterialTheme.typography.body1
            )
        }
    }

Vous pouvez également utiliser l'API isAvailableOnDevice du fournisseur pour vérifier s'il est disponible et si les certificats sont configurés correctement. Pour ce faire, vous pouvez appeler la méthode isAvailableOnDevice qui renvoie la valeur "false" si le fournisseur n'est pas configuré correctement.

val context = LocalContext.current
LaunchedEffect(Unit) {
   if (provider.isAvailableOnDevice(context)) {
       Log.d(TAG, "Success!")
   }
}

Mises en garde

Plusieurs mois sont nécessaires pour que les nouvelles polices Google Fonts soient disponibles sur Android. Il existe un intervalle de temps entre le moment où une police est ajoutée sur fonts.google.com et sa disponibilité via l'API de polices téléchargeables (dans le système de vue ou dans Compose). Les polices qui viennent d'être ajoutées risquent de ne pas se charger dans votre application et de générer une erreur IllegalStateException. Pour aider les développeurs à identifier cette erreur par rapport aux autres types d'erreurs de chargement de police, nous avons ajouté un message descriptif pour cette exception dans Compose en précisant les modifications ici.