Stile paragrafo

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

Impostare l'allineamento del testo

Il parametro textAlign consente di impostare l'allineamento orizzontale del testo all'interno di una superficie componibile Text.

Per impostazione predefinita, Text seleziona 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 арабский o иврит

@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 composable Text, ti consigliamo di utilizzare TextAlign.Start e TextAlign.End anziché TextAlign.Left e TextAlign.Right, rispettivamente, in quanto si risolvono nel bordo destro del composable Text in base all'orientamento del testo della lingua preferito. Ad esempio, TextAlign.End si allinea al lato destro per il testo francese e al lato sinistro per il testo arabo, ma 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 arbitrari. Una volta contrassegnata con ParagraphStyle, la parte di testo viene distinta dal resto del testo come se avesse dei ritorni a capo all'inizio e alla fine.

Per ulteriori informazioni sull'aggiunta di più stili in un testo, consulta Aggiungere più stili in un testo.

AnnotatedString ha un costruttore a prova di tipo per semplificarne la creazione: 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 normale

Regolare l'altezza della riga e la spaziatura interna

includeFontPadding è una proprietà precedente che aggiunge spaziatura aggiuntiva in base alle misure dei caratteri nella parte superiore della prima riga e in quella inferiore dell'ultima riga di un testo. A partire dalla versione 2024.01.01 del BOM di Compose, includeFontPadding è impostato su false per impostazione predefinita, il che rende il layout del testo predefinito più in linea con gli 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 del testo all'interno dello spazio e rimuovere gli spazi vuoti.

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

Immagine che mostra lineHeight come misurazione basata sulle linee direttamente sopra e sotto.
Figura 1. Utilizza Allineamento e Taglia per modificare il testo all'interno dell'insieme lineHeighte taglia gli spazi extra, 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 modificare lineHeight, ora puoi centrare e applicare stili al testo utilizzando configurazioni con l'API sperimentale LineHeightStyle: LineHeightStyle.Alignment e LineHeightStyle.Trim (includeFontPadding deve essere impostato su false per far funzionare la funzionalità Taglia). L'allineamento e il 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 riga nello spazio fornito dall'altezza della riga. All'interno di ogni riga, puoi allineare il testo in alto, in basso, al centro o proporzionalmente. LineHeightStyle.Trim ti consente quindi di lasciare o rimuovere lo spazio aggiuntivo nella parte superiore della prima riga e nella parte inferiore dell'ultima riga del testo, generato da eventuali aggiustamenti di lineHeight e Allineamento. Gli esempi riportati di seguito mostrano l'aspetto del testo su più righe con diverse 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

Leggi il post del blog Correzione dell'aggiustamento del carattere nel testo di composizione per scoprire di più sul contesto di questa modifica, sul funzionamento di includeFontPadding nel sistema di visualizzazione e sulle modifiche apportate a Scrivi e alle 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 a capo che preferisci nel TextStyle blocco del composable Text. I tipi di interruzione di riga preimpostati includono quanto segue:

  • Simple: interruzione di riga di base e veloce. Consigliato per i campi di immissione di testo.
  • Heading: a capo con regole di a capo meno rigide. Consigliato per testo breve, ad esempio titoli.
  • Paragraph: interruzioni di riga più lente e di qualità superiore per una maggiore leggibilità. Consigliata per quantità maggiori di testo, ad esempio paragrafi.

Il seguente snippet utilizza sia Simple che Paragraph per specificare il comportamento di interruzione 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 strategia di interruzione di riga semplice rispetto a un blocco di testo con una strategia di interruzione ottimizzata per il paragrafo. Il blocco di testo con la strategia di interruzione di riga semplice presenta una maggiore variabilità nelle lunghezze delle righe.
Figura 1. Un blocco di testo con una semplice strategia di a capo (sopra) rispetto a un blocco di testo con a capo ottimizzati per i paragrafi (sotto).

Nell'output riportato sopra, tieni presente che il comportamento di interruzione riga Paragraph produce un risultato visivamente più equilibrato rispetto all'interruzione 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 le lunghezze delle righe del testo, applicando anche la suddivisione in sillabe automatica, se abilitata. Consigliata per schermi piccoli, come gli orologi, per massimizzare la quantità di testo visualizzata.
  • HighQuality: ottimizza un paragrafo per ottenere un testo più leggibile, inclusa la suddivisione in sillabe, se abilitata. Deve essere un valore predefinito per tutto ciò che non è Balanced o Simple.
  • Simple: strategia di base e rapida. Se l'opzione è attivata, l'accavallamento viene eseguito solo per le parole che da sole non rientrano in un'intera riga. 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 Balanced strategia di interruzione di riga:

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 equilibrata e un paragrafo
  formattato senza una strategia. Il paragrafo con la strategia di interruzione delle righe bilanciata ha lunghezze di riga più coerenti rispetto a quelle predefinite.
Figura 2. Un paragrafo formattato con una Balanced strategia di a capo (sopra) rispetto a un paragrafo formattato senza una strategia di a capo.

Considerazioni sui caratteri CJK

Puoi anche personalizzare LineBreak con le API Strictness e WordBreak, progettate appositamente per le lingue CJK. Gli effetti di queste API potrebbero non essere sempre visibili nelle lingue diverse dal CJK. In generale, le regole di interruzione di riga sono definite in base alle impostazioni internazionali.

Strictness descrive la severità del taglio riga con le seguenti proprietà:

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

WordBreak definisce la modalità di inserimento dei ritorni 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.

Lo snippet seguente utilizza un'impostazione di severità Strict e di interruzione delle parole Phrase per un testo 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 severità e interruzione di parole rispetto al testo predefinito.
Figura 3. Testo formattato con le impostazioni Strictness e WordBreak (sopra) rispetto al testo formattato solo con LineBreak.Heading (sotto).

Mettere i trattini al testo suddiviso in più righe

L'API Hyphens ti consente di aggiungere il supporto per l'accavallamento alla tua app. L'accavallamento si riferisce all'inserimento di un segno di punteggiatura simile a un trattino per indicare che una parola è divisa tra righe di testo. Se questa opzione è attivata, l'a capo viene aggiunto tra le sillabe di una parola nei punti di a capo appropriati.

Per impostazione predefinita, l'accavallamento non è abilitato. Per attivare l'accatastamento, aggiungiHyphens.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 con l'accavallamento delle parole disattivato e un paragrafo con l'accavallamento delle parole attivato.
  Quando l'accavallamento è abilitato, una parola viene suddivisa in due righe.
Figura 4. Un paragrafo con l'accavallamento delle parole disattivato (sopra) e un paragrafo con l'accavallamento delle parole attivato (sotto).

Se è attivata, l'accavallamento delle parole avviene solo alle seguenti condizioni:

  • Una parola non sta in una riga. Se utilizzi una strategia di interruzione Simple, la sillabazione di una parola avviene solo se una riga è più breve della singola parola.
  • Sul dispositivo è impostata la locale appropriata, mentre l'accavallamento delle parole è determinato utilizzando i dizionari presenti nel sistema.