Stile paragrafo

In questa pagina viene descritto come modificare lo stile del 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 una superficie componibile Text.

Per impostazione predefinita, Text seleziona l'allineamento naturale del testo in base al valore dei contenuti:

  • 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 arbitrarie. Una volta contrassegnata con ParagraphStyle, la parte di testo viene distinta dal testo rimanente 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 sicuro per i tipi 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 di 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. Usa Allineamento e Taglia per regolare il testo all'interno del set lineHeight e, se necessario, taglia gli spazi aggiuntivi.

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

Leggi il post del blog Correzione dell'interno 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 per Scrivi e le nuove API LineHeightStyle.

Inserisci 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 rapida e basilare. Consigliato per i campi di immissione di testo.
  • Heading: interruzione di riga con regole di interruzione meno restrittive. Consigliato per testo breve, ad esempio titoli.
  • Paragraph: interruzioni di riga più lente e di qualità superiore per una maggiore leggibilità. Consigliato per grandi quantità di testo, come i paragrafi.

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

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 i paragrafi. 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 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, 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:

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

Considerazioni sui caratteri CJK

Puoi anche personalizzare LineBreak con le API Strictness e WordBreak, che sono state progettate specificatamente per i linguaggi CJK. Gli effetti di queste API potrebbero non essere sempre visibili nelle lingue diverse dal CJK. Nel complesso, 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 (in alto) rispetto al testo formattato solo con LineBreak.Heading (in basso).

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

Quando questa opzione è abilitata, la sillabazione si verifica 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 sono impostate le impostazioni internazionali appropriate, secondo la scelta della sillabazione appropriata mediante i dizionari presenti nel sistema.