Stile paragrafo

Questa pagina descrive come formattare il testo del paragrafo. Per impostare lo stile a livello di paragrafo, puoi configurare parametri come textAlign e lineHeight o definire il tuo ParagraphStyle.

Impostare l'allineamento del testo

Il parametro textAlign consente di impostare l'allineamento orizzontale del testo all'interno di un'area di composizione Text.

Per impostazione predefinita, Text selezionerà l'allineamento naturale del testo in base al valore del contenuto:

  • Bordo sinistro del contenitore Text per alfabeti da sinistra a destra come latino, cirillico o hangul
  • Bordo destro del contenitore Text per alfabeti da destra a sinistra come arabo o ebraico

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

Le parole

Se vuoi impostare manualmente l'allineamento del testo di un componente componibile Text, preferisci utilizzare TextAlign.Start e TextAlign.End anziché TextAlign.Left e TextAlign.Right rispettivamente, in quanto si risolvono sul bordo destro del componente componibile Text a seconda dell'orientamento del testo della lingua preferita. Ad esempio, TextAlign.End si allinea al lato destro per il testo in francese e al lato sinistro per il testo in arabo, mentre TextAlign.Right si allinea al lato destro indipendentemente dall'alfabeto utilizzato.

Aggiungere più stili in un paragrafo

Per aggiungere più stili in un paragrafo, puoi utilizzare ParagraphStyle in un AnnotatedString, che può essere annotato con stili di annotazioni arbitrarie. Una volta che una parte del testo è contrassegnata con un ParagraphStyle, questa parte viene separata dal resto del testo come se avesse avanzamenti riga all'inizio e alla fine.

Per saperne di più sull'aggiunta di più stili in un testo, vedi Aggiungere più stili in un testo.

AnnotatedString ha un builder type-safe per semplificare la creazione di: buildAnnotatedString. Il seguente snippet utilizza buildAnnotatedString per impostare 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")
            }
        }
    )
}

Tre paragrafi in tre stili diversi: blu, rosso e in grassetto e nero semplice

Regolare l'altezza della riga e la spaziatura interna

includeFontPadding è una proprietà legacy che aggiunge un riempimento aggiuntivo in base alle metriche del carattere nella parte superiore della prima riga e in quella inferiore dell'ultima riga di un testo. A partire dalla versione 2024.01.01 della BOM di Compose, includeFontPadding è impostato su false per impostazione predefinita, il che allinea il layout di testo predefinito a strumenti di progettazione comuni.

La possibilità di configurare lineHeight non è una novità: è disponibile da Android Q. Puoi configurare lineHeight per Text utilizzando il parametro lineHeight, che distribuisce l'altezza della riga in ogni riga di testo. Puoi quindi utilizzare il nuovo LineHeightStyle API per configurare ulteriormente l'allineamento di questo testo all'interno dello spazio e rimuovere gli spazi bianchi.

Per una maggiore precisione, ti consigliamo di regolare lineHeight utilizzando l'unità di testo "em" (dimensione del carattere relativa) anziché "sp" (pixel scalati). Per ulteriori informazioni sulla selezione di un'unità di testo appropriata, vedi TextUnit.

Immagine che mostra l'altezza della linea come misurazione basata sulle linee direttamente sopra e sotto.
Figura 1. Utilizza Allineamento e Taglio per regolare il testo all'interno del lineHeight e tagliare lo spazio aggiuntivo, se necessario.

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

Oltre a regolare lineHeight, ora puoi centrare e formattare ulteriormente il testo utilizzando le configurazioni con l'API LineHeightStyle: LineHeightStyle.Alignment e LineHeightStyle.Trim (includeFontPadding deve essere impostato su false per il funzionamento del taglio). Allineamento e Taglio utilizzano lo spazio misurato tra le righe di testo per distribuirlo in modo più appropriato a tutte le righe, inclusa una singola riga di testo e la riga superiore di un blocco di testo.

LineHeightStyle.Alignment definisce come allineare la linea nello spazio fornito dall'altezza della riga. All'interno di ogni riga, puoi allineare il testo in alto, in basso, al centro o in modo proporzionale. LineHeightStyle.Trim ti consente di lasciare o rimuovere lo spazio aggiuntivo nella parte superiore della prima riga e in quella inferiore dell'ultima riga del testo, generato da eventuali regolazioni di lineHeight e allineamento. Gli esempi seguenti mostrano l'aspetto del testo su più righe con varie configurazioni di LineHeightStyle.Trim quando l'allineamento è centrato (LineHeightStyle.Alignment.Center).

Un'immagine che mostra LineHeightStyle.Trim.None Un'immagine che mostra LineHeightStyle.Trim.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Un'immagine che mostra LineHeightStyle.Trim.FirstLineTop Un'immagine che mostra LineHeightStyle.Trim.LastLineBottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

Consulta il post del blog Fixing Font Padding in Compose Text per saperne di più sul contesto di questa modifica, su come funzionava includeFontPadding nel sistema View e sulle modifiche apportate per Compose e le nuove API LineHeightStyle.

Inserire interruzioni di riga

L'API LineBreak definisce i criteri in base ai quali il testo viene suddiviso su più righe. Puoi specificare il tipo di interruzione di riga che vuoi nel blocco TextStyle del componente componibile Text. I tipi di interruzione di riga preimpostati includono:

  • Simple: interruzione di riga rapida e di base. Consigliato per i campi di inserimento del testo.
  • Heading: interruzione di riga con regole di interruzione meno rigide. Consigliato per testi brevi, come i titoli.
  • Paragraph: interruzione di riga più lenta e di qualità superiore per una migliore leggibilità. Consigliato per quantità maggiori di testo, ad esempio i paragrafi.

Il seguente snippet utilizza sia Simple che Paragraph per specificare il comportamento di interruzione di riga in un blocco di testo lungo:

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

Un blocco di testo che mostra una semplice strategia di interruzione di riga rispetto a un blocco di testo con una strategia di interruzione ottimizzata per i paragrafi. Il blocco di testo con la strategia di interruzione
di riga semplice presenta una maggiore variabilità nella lunghezza delle righe.
Figura 1. Un blocco di testo con una semplice strategia di interruzione di riga (in alto) rispetto a un blocco di testo con interruzione di riga ottimizzata per il paragrafo (in basso).

Nell'output riportato sopra, nota che il comportamento di interruzione di riga Paragraph produce un risultato visivamente più equilibrato rispetto all'interruzione di riga Simple.

Personalizzare le interruzioni di riga

Puoi anche creare la tua configurazione LineBreak con il parametro Strategy. Strategy può essere uno dei seguenti:

  • Balanced: tenta di bilanciare la lunghezza delle righe di testo, applicando anche la sillabazione automatica, se abilitata. Consigliato per schermi piccoli, come gli orologi, per massimizzare la quantità di testo visualizzato.
  • HighQuality: ottimizza un paragrafo per un testo più leggibile, inclusa la sillabazione, se attivata. (Deve essere un valore predefinito per tutto ciò che non è Balanced o Simple.)
  • Simple: strategia di base e veloce. Se abilitata, la sillabazione viene eseguita solo per le parole che non rientrano in una riga intera. Utile per modificare il testo per evitare di cambiare posizione durante la digitazione.

Il seguente snippet mostra la differenza tra un paragrafo con impostazioni predefinite e un paragrafo ottimizzato per schermi piccoli con la strategia di interruzione di riga 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
            )
        }
    )
)

Un paragrafo con una strategia di interruzione di riga bilanciata e un paragrafo
  formattato senza una strategia. Il paragrafo con la strategia di interruzione di riga bilanciata
  ha lunghezze di riga più uniformi rispetto a quella predefinita.
Figura 2. Un paragrafo formattato con una Balanced strategia di interruzione di riga (in alto) rispetto a un paragrafo formattato senza una strategia di interruzione di riga.

Considerazioni relative a CJK

Puoi anche personalizzare LineBreak con le API Strictness e WordBreak, che sono state progettate appositamente per le lingue CJK. Potresti non vedere sempre gli effetti di queste API nelle lingue non CJK. Nel complesso, le regole di interruzione di riga sono definite in base alle impostazioni internazionali.

Strictness descrive la rigidità dell'interruzione di riga con le seguenti proprietà:

  • Default: regole di interruzione predefinite per le impostazioni internazionali. Potrebbe corrispondere a Normal o Strict.
  • Loose: le regole meno restrittive. Adatto a righe brevi.
  • Normal: le regole più comuni per l'interruzione di riga.
  • Strict: le regole più rigorose per l'interruzione di riga.

WordBreak definisce la modalità di inserimento degli a capo all'interno delle parole con le seguenti proprietà:

  • Default: regole di interruzione predefinite per le impostazioni internazionali.
  • Phrase: l'interruzione di riga si basa sulle frasi.

Il seguente snippet utilizza un'impostazione di rigore Strict e di interruzione delle parole Phrase per un testo in giapponese:

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

Testo giapponese con impostazioni di rigore e interruzione di parola rispetto al testo predefinito.
Figura 3. Testo formattato con le impostazioni Strictness e WordBreak (in alto) rispetto al testo formattato solo con LineBreak.Heading (in basso).

Inserire il trattino nel testo suddiviso su più righe

L'API Hyphens ti consente di aggiungere il supporto della sillabazione alla tua app. Il termine sillabazione si riferisce all'inserimento di un segno di punteggiatura simile a un trattino per indicare che una parola è divisa su più righe di testo. Se attivata, la sillabazione viene aggiunta tra le sillabe di una parola nei punti di sillabazione appropriati.

Per impostazione predefinita, la sillabazione non è abilitata. Per attivare la sillabazione, aggiungi Hyphens.Auto come parametro in un blocco 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
                )
            )
        }
    )
)

Un paragrafo senza la sillabazione attivata e un paragrafo con la sillabazione attivata.
  Quando la sillabazione è abilitata, una parola viene sillabata e divisa su due righe.
Figura 4. Un paragrafo senza la sillabazione attivata (in alto) e un paragrafo con la sillabazione attivata (in basso).

Se attivata, la sillabazione si verifica solo nelle seguenti condizioni:

  • Una parola non entra in una riga. Se utilizzi una strategia di interruzione di riga Simple, la sillabazione di una parola si verifica solo se una riga è più corta della singola parola.
  • Sul dispositivo è impostata la lingua appropriata, in quanto la sillabazione appropriata viene determinata utilizzando i dizionari presenti nel sistema.