Appliquer un style à un paragraphe

Cette page explique comment ajouter un style au texte de votre paragraphe. Pour définir un style au niveau du paragraphe, vous pouvez configurer des paramètres tels que textAlign et lineHeight, ou définir votre propre ParagraphStyle.

Définir l'alignement du texte

Le paramètre textAlign vous permet de définir l'alignement horizontal 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

@Composable
fun CenterText() {
    Text(
        "Hello World", textAlign = TextAlign.Center, modifier = Modifier.width(150.dp)
    )
}

Les mots

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

Ajouter plusieurs styles dans un paragraphe

Pour ajouter plusieurs styles dans un paragraphe, vous pouvez utiliser ParagraphStyle dans un AnnotatedString, qui peut être annoté avec des styles d'annotations arbitraires. Une fois qu'une partie de votre 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.

Pour en savoir plus sur l'ajout de plusieurs styles dans un texte, consultez la section Ajouter plusieurs styles dans un texte.

AnnotatedString dispose d'un compilateur de sûreté du typage pour faciliter la création: buildAnnotatedString. L'extrait suivant utilise buildAnnotatedString pour définir ParagraphStyle:

@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

Ajuster la hauteur de ligne et la marge intérieure

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. À partir de la version 2024.01.01 de la nomenclature Compose, includeFontPadding est défini sur false par défaut, ce qui rapproche la mise en page de texte par défaut des outils de conception courants.

La possibilité de configurer lineHeight n'est pas nouvelle. Elle est disponible depuis Android Q. Vous pouvez configurer lineHeight pour Text à l'aide du paramètre lineHeight, qui distribue la hauteur de ligne dans chaque ligne de texte. Vous pouvez ensuite utiliser le nouveau LineHeightStyle API pour configurer plus en détail l'alignement de ce texte dans l'espace et supprimer les espaces vides.

Vous pouvez ajuster lineHeight à l'aide de l'unité de texte "em" (taille de police relative) au lieu de "sp" (pixels mis à l'échelle) pour améliorer la précision. Pour en savoir plus sur la sélection d'une unité de texte appropriée, consultez TextUnit.

Image montrant la valeur lineHeight en tant que mesure basée sur les lignes situées directement au-dessus et en-dessous.
Figure 1. Utilisez les options "Alignement" et "Recadrer" pour ajuster le texte dans l'ensemble lineHeight, et coupez l'espace supplémentaire si nécessaire.

Text(
    text = text,
    style = LocalTextStyle.current.merge(
        TextStyle(
            lineHeight = 2.5.em,
            platformStyle = PlatformTextStyle(
                includeFontPadding = false
            ),
            lineHeightStyle = LineHeightStyle(
                alignment = LineHeightStyle.Alignment.Center,
                trim = LineHeightStyle.Trim.None
            )
        )
    )
)

En plus d'ajuster lineHeight, vous pouvez désormais centrer et styliser davantage le texte à l'aide de configurations avec l'API expérimentale LineHeightStyle: LineHeightStyle.Alignment et LineHeightStyle.Trim (includeFontPadding doit être défini sur false pour que le forçage de la taille fonctionne). L'alignement et le recadrage utilisent l'espace mesuré entre les lignes de texte pour le répartir plus judicieusement sur toutes les lignes, y compris une seule ligne de texte et la ligne supérieure d'un bloc de texte.

LineHeightStyle.Alignment définit comment aligner la ligne dans l'espace fourni par la hauteur de ligne. Dans chaque ligne, vous pouvez aligner le texte en haut, en bas, au centre ou de manière proportionnelle. LineHeightStyle.Trim vous permet ensuite de laisser ou de supprimer l'espace supplémentaire en haut de la première ligne et en bas de la dernière ligne de votre texte, généré à partir de tout ajustement lineHeight et d'alignement. Les exemples suivants montrent à quoi ressemble le texte multiligne avec différentes configurations LineHeightStyle.Trim lorsque l'alignement est centré (LineHeightStyle.Alignment.Center).

Image illustrant LineHeightStyle.Trim.None Image illustrant LineHeightStyle.Trim.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Image illustrant LineHeightStyle.Trim.FirstLineTop Image illustrant LineHeightStyle.Trim.LastLineBottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

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.

Insérer des sauts de ligne

L'API LineBreak définit les critères en fonction desquels le texte est divisé sur plusieurs lignes. Vous pouvez spécifier le type de coupure de ligne souhaité dans le bloc TextStyle de votre composable Text. Les types de coupure de ligne prédéfinis incluent les suivants:

  • Simple : coupure de ligne rapide et de base. Recommandé pour les champs de saisie de texte.
  • Heading : saut de ligne avec des règles de saut plus souples. Recommandé pour le texte court, comme les titres.
  • Paragraph : saut de ligne plus lent et de meilleure qualité pour améliorer la lisibilité. Recommandé pour les textes plus longs, comme les paragraphes.

L'extrait de code suivant utilise à la fois Simple et Paragraph pour spécifier le comportement de coupure de ligne sur un long bloc de texte:

TextSample(
    samples = mapOf(
        "Simple" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Simple
                )
            )
        },
        "Paragraph" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph
                )
            )
        }
    )
)

Bloc de texte qui présente une stratégie de coupure de ligne simple par rapport à un bloc de texte avec une stratégie de coupure optimisée pour les paragraphes. Le bloc de texte avec la stratégie de coupure de ligne simple présente une plus grande variabilité des longueurs de ligne.
Figure 1. Bloc de texte avec une stratégie de coupure de ligne simple (en haut) par rapport à un bloc de texte avec une coupure de ligne optimisée pour les paragraphes (en bas).

Dans la sortie ci-dessus, notez que le comportement de coupure de ligne Paragraph produit un résultat plus équilibré visuellement que celui de la coupure de ligne Simple.

Personnaliser les sauts de ligne

Vous pouvez également créer votre propre configuration LineBreak avec le paramètre Strategy. L'élément Strategy peut être l'un des éléments suivants:

  • Balanced : tente d'équilibrer les longueurs de ligne du texte, et applique également le césure automatique si cette option est activée. Recommandé pour les petits écrans, comme les montres, afin de maximiser la quantité de texte affichée.
  • HighQuality : optimise un paragraphe pour améliorer la lisibilité du texte, y compris l'espacement des mots s'il est activé. (Doit être la valeur par défaut pour tout ce qui n'est pas Balanced ou Simple.)
  • Simple : stratégie de base et rapide. Si cette option est activée, le césure n'est effectué que pour les mots qui ne tiennent pas sur une ligne entière. Utile pour modifier le texte afin d'éviter de changer de position pendant la saisie.

L'extrait de code suivant montre la différence entre un paragraphe avec les paramètres par défaut et un paragraphe optimisé pour les petits écrans avec la stratégie de coupure de ligne Balanced:

TextSample(
    samples = mapOf(
        "Balanced" to {
            val smallScreenAdaptedParagraph =
                LineBreak.Paragraph.copy(strategy = LineBreak.Strategy.Balanced)
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(200.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = smallScreenAdaptedParagraph
                )
            )
        },
        "Default" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(200.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default
            )
        }
    )
)

Paragraphe avec une stratégie de saut de ligne équilibrée et paragraphe mis en forme sans stratégie. Le paragraphe avec la stratégie de retour à la ligne équilibrée présente des longueurs de ligne plus cohérentes que la valeur par défaut.
Figure 2. Paragraphe mis en forme avec une stratégie de coupure de ligne Balanced (en haut) par rapport à un paragraphe mis en forme sans stratégie de coupure de ligne.

Considérations concernant les scripts CJC

Vous pouvez également personnaliser LineBreak avec les API Strictness et WordBreak, qui ont été conçues spécifiquement pour les langues CJK. Les effets de ces API ne sont pas toujours visibles dans les langues autres que CJK. De manière générale, les règles de coupure de ligne sont définies en fonction des paramètres régionaux.

Strictness décrit la rigueur de la coupure de ligne avec les propriétés suivantes:

  • Default : règles de rupture par défaut pour les paramètres régionaux. Peut correspondre à Normal ou Strict.
  • Loose : règles les moins restrictives. Convient aux lignes courtes.
  • Normal : règles les plus courantes pour le forçage de la ligne.
  • Strict : règles les plus strictes pour le forçage de la ligne.

WordBreak définit la manière dont les retours à la ligne doivent être insérés dans les mots avec les propriétés suivantes:

  • Default : règles de rupture par défaut pour les paramètres régionaux.
  • Phrase : le retour à la ligne est basé sur des phrases.

L'extrait de code suivant utilise une sévérité Strict et un paramètre de coupure de mot Phrase pour un texte japonais:

val customTitleLineBreak = LineBreak(
    strategy = LineBreak.Strategy.HighQuality,
    strictness = LineBreak.Strictness.Strict,
    wordBreak = LineBreak.WordBreak.Phrase
)
Text(
    text = "あなたに寄り添う最先端のテクノロジー。",
    modifier = Modifier.width(250.dp),
    fontSize = 14.sp,
    style = TextStyle.Default.copy(
        lineBreak = customTitleLineBreak
    )
)

Texte en japonais avec les paramètres "Strictness" (Exigence) et "WordBreak" (Rupture de mot) par rapport au texte par défaut.
Figure 3. Texte mis en forme avec les paramètres Strictness et WordBreak (en haut) par rapport au texte mis en forme uniquement avec LineBreak.Heading (en bas).

Traiter le texte scindé sur plusieurs lignes

L'API Hyphens vous permet d'ajouter la césure à votre application. La césure consiste à insérer un signe de ponctuation semblable à un tiret pour indiquer qu'un mot est divisé sur plusieurs lignes de texte. Lorsqu'elle est activée, la césure est ajoutée entre les syllabes d'un mot aux points de césure appropriés.

Par défaut, le césure n'est pas activé. Pour activer le césure, ajoutez Hyphens.Auto comme paramètre dans un bloc TextStyle:

TextSample(
    samples = mapOf(
        "Hyphens - None" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph,
                    hyphens = Hyphens.None
                )
            )
        },
        "Hyphens - Auto" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph,
                    hyphens = Hyphens.Auto
                )
            )
        }
    )
)

Paragraphe sans césure activée et paragraphe avec césure activée.
  Lorsque le césure est activé, un mot est césuré et divisé sur deux lignes.
Figure 4. Paragraphe sans césure activée (en haut) et paragraphe avec césure activée (en bas).

Lorsque l'option est activée, le césure ne s'applique que dans les conditions suivantes:

  • Un mot ne tient pas sur une ligne. Si vous utilisez une stratégie de coupure de ligne Simple, le césure d'un mot ne se produit que si une ligne est plus courte que le mot seul.
  • Les paramètres régionaux appropriés sont définis sur votre appareil, car la césure appropriée est déterminée à l'aide des dictionnaires présents dans le système.